Mr. Script

Many IPs, One NIC? No Problem.

If you've been wanting to bind multiple IP addresses to a single NIC, now you can.

The other day I had to scold my son for trying to take his brother's Popsicle after he'd finished his own. "Don't be greedy," I told him. "You had yours, let Bubba have his." Of course, he started crying, and I felt my resolve wavering. His tears brought me to the verge of my own tears, but I stuck to my guns and he got the message: Greed is bad.

The next day, I received this e-mail from a reader named Prasad: I've been trying to add multiple IP addresses to the same NIC interface using WMI and didn't have any success. On UNIX platforms, this can be easily done using ifconfig. I'm hoping there is an equivalent on Windows, but I couldn't find any.

My first thought was: Why do you need so many IP addresses? You need to share! After I stopped thinking like a father, I realized there were lots of reasons you might want to bind multiple IP addresses to a single NIC. A Web server with multiple virtual servers is one example that comes to mind. So, to answer Prasad's question, "Can it be done?" Why, of course!

A Few Assumptions
Because we're binding multiple IP addresses to a single NIC, we're assuming that it's the only NIC installed. If you have a multi-homed machine, you'll need to take steps to identify the correct NIC. Even if you don't have multiple NICs, you probably do have an IEEE 1394 (Firewire) adapter or other hardware that Windows "sees" as a NIC. As such, we need to filter out devices that don't have IP enabled to ensure that we're configuring the correct NIC.



Multi_IP.wsf
Retrieves IP addresses from a database
and binds them to a single NIC



    <>
id="objConn" progid="ADODB.Connection" Reference/>
    <> id="objRS" progid="ADODB.Recordset" Reference/>
    <> language="VBScript">
      Dim strIPAddr(), strSNMask(), strGW()
objConn.Open "DSN=IPData;"
      objRS.CursorLocation = adUseClient
      objRS.Open "SELECT * FROM IPAddresses", _
        objConn, _
        adOpenStatic, _
        adLockOptimistic

      objRS.MoveFirst
      iRC=objRS.RecordCount
      ReDim strIPAddr(iRC)
      ReDim strSNMask(iRC)
      ReDim strGW(iRC)
      iCount=0
      'Store IP addr, SN mask, and GW into arrays
      Do Until objRS.EOF
        strIPAddr(iCount)=objRS.Fields.Item("IP")
        strSNMask(iCount)=objRS.Fields.Item("Mask")
        strGW(iCount)=objRS.Fields.Item("GW")
        iCount=iCount+1
        objRS.MoveNext
      Loop
      objRS.Close
      objConn.Close

'Bind the addresses to the NIC
      strGWMetric = Array(1)
      Set objWMI =GetObject("winmgmts:\\.\root\cimv2")
      Set colNICs = objWMI.ExecQuery _
        ("Select * from " _
        & "Win32_NetworkAdapterConfiguration " _
        & "where IPEnabled=TRUE")
      For Each objNIC in colNICs
      bErr1 = objNIC.EnableStatic _
        "(strIPAddr, strSNMask)
      bErr2 = objNIC.SetGateways _
        "(strGW, strGWMetric)
      Next
   
  

Two for One
We've used ActiveX Data Objects (ADO) to retrieve the IP address data from an Access database, and connected to that database using a Data Source Name (DSN) rather than connecting directly.

Figure 1 shows the IPAddresses table that holds our data. It may seem like a waste of space to repeat the same subnet mask and default gateway in each row, but by structuring our data this way, it allows for flexibility in case the multiple addresses we're binding happen to belong to different networks (for instance, if this was a notebook computer that connected to several different networks).

Figure 1. Each IP address has a corresponding subnet mask and default gateway.
Figure 1. Each IP address has a corresponding subnet mask and default gateway. (Click image to view larger version.)

Binded by the Light
After reading the data into the arrays, we then bind the multiple IP addresses to the NIC. The good news is that WMI makes this easy. In fact, because the IP Address property is stored as an array, the actual process of binding multiple addresses is exactly the same as binding a single address. The only difference is the size of the array. Speaking of arrays, you'll notice that I used the ReDim keyword to reallocate space for the array once I knew how many records I was dealing with. Anytime you need to allocate array space based on dynamic data, use ReDim. Just remember to declare an empty array (Dim strIPAddr()) first.

You may have valid reasons for not wanting to connect to the database via the DSN. Hey, I'm not here to judge. If you'd rather connect directly, that's your business. Just replace your Open statement with this:

objConn.Open "Provider =
Microsoft.Jet.OLEDB.4.0; Data Source =
C:\IPAddress.mdb"

No Guts, No Glory
Now that you've had a taste of the power of ADO, dive in and really get familiar with it. It adds a whole new dimension to scripting.

About the Author

Chris Brooke, MCSE, is a contributing editor for Redmond magazine and director of enterprise technology for ComponentSource. He specializes in development, integration services and network/Internet administration. Send questions or your favorite scripts to chrisb@componentsource.com.

comments powered by Disqus

Reader Comments:

Wed, Mar 12, 2008 Anonymous Anonymous

This is an excellent article.

Thu, Jul 20, 2006 saran siemreap

how to get IP in to our computer

Mon, Aug 15, 2005 Anonymous Anonymous

Multiple virtual web servers on windows? Got LINUX!

Thu, Aug 19, 2004 Ray Eaker Savannah, GA

The reader looking for a way to set an IP address via command line might be interested in the NETSH command. The following will provide help with setting the IP address, Gateway, DNS or WINS:

NETSH INTERFACE IP help

Wed, Aug 18, 2004 Ross Presser Bridgeport NJ

I know this is the scripting column, but I wanted to point out that multiple IPs per NIC has been available, through the configuration dialogs, since Windows NT 3.51. This isn't a new feature at all... it's a mandatory part of any TCP-IP stack.

Tue, Aug 17, 2004 Dave Phillips Phoenix Arizona

Nice article. However, where is the script from the previous article regarding enumerating, enabling, or disabling NIC's via the Windows Shell ? We have a distinct need for this to simulate intermittent network communications failure for a real-time client application. I am currently using a script that simply modifies the IP address, but would prefer to set the NIC off-line.

Add Your Comment Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Comment:
Please type the letters/numbers you see above

Redmond Tech Watch

Sign up for our newsletter.

I agree to this site's Privacy Policy.