Salt * Wet * Bytes

October 17, 2009

Getting the network adapters’ order in Windows

Filed under: AdminScripts, Networking — saltwetfish @ 7:22 am
Tags: , ,

Now, one of the biggest problem for us when deployment new servers is that we want to get everything as automated as possible. One of the most complex to automate is networking configuration. That is, you need to figure out which nic to team and which to set as heartbeat or backup nic, etc. In this, I use nic and network adapter interchangeably.

The most persistent problem is getting a ordered list of network adapters from Windows. Windows itself does not present nics in any order. So your slot 0 (embedded) port 1 could be named as “local area network connection 3″ or called “Broadcom 1GB PCI Ethernet Adapter 4″ and the slot 10 port 2 nic could be named as the first nic.

We have a standard for deploying servers. The first nic (usually the embedded port 1) is teamed with the first nic card’s port 1 (e.g. slot 2 port 1). Port 2 Embedded is used for backup and the 4th port (in this case, Slot 2 port 2) is used of heartbeat if its a cluster. Now why do we want to do that? The basic idea is that this reduce logistic work for the cabling people and for us also. We all know which port is used for what and don’t have to keep referring to deployment documents when configuring nics (except to get the ip addresses).

If you look into the register, there is a value in HKLM\CurrentControlSet\System\Enum\PCI keys (or the nic’s enum keys) which presents the network adapter with “LocationInformation” with “PCI bus X, device Y, function Z”.

  • The smaller the PCI number. e.g PCI bus 1, the higher the order of the nic, ie. first nic.
  • The smaller the function number within the same PCI bus, the higher the order of the nic, i.e. function 0 could be port 1 and function 1 port 2

Note: I am only talking about network adapters here.

With this information its very easy then to grab this registry value and transform it into some ranking system for the nics. The formula is very easy, multiple PCI number by 10 and add the function number to it (i.e ranking = (10 x pci number) + function number). The smaller the number the higher up in the order.

So all we need to do now is to:

  • use WMI win32_networkadapter to loop through all nics,
  • grab their DeviceID and PNPDevicID (which is the registery key under ENUM, e.g. PCI\VEN_10DE&DEV_07DC&SUBSYS_2A65103C&REV_A2\3&2411E6FE&1&78.
  • Use the PNPDeviceID to look for the LocationInformation value,
  • Create the ranking and sort them and pump them into a dictionary object with the ranking number (I transform those numbers to absolute ranking,e.g. 1, 2,3,etc) and the deviceID.

The final result in the dictionary object should look something like this (where key is the ranking and item is DeviceID of the network adapter):

key     item
==      ===
1        11
2        7
3        12
4        9
5        8

So now all I need is to grab the deviceIDs of order pair nic with ranking 1 and 3 and team them, get the rank 2 and setup the backup IP addresss, etc

Now I created the scripts and got it working on Windows 2003. Then I tried it on Windows 2008 and it failed!

When I looked at the registry value, the LocationInformation is now something like this:

@system32\drivers\pci.sys,#65536;PCI bus %1, device %2, function %3;(3,0,0)

My jaw dropped to think that I finally cracked it and Windows 2008 changed the format. I couldn’t believe my eyes to think that now I cannot easily get PCI and function numbers from registry. I searched the Internet for some answers and all pointed to using some device programming function to retrieve these values.

However, I started to looked a few more of these values, I found something was different in each value. I looked closer and voila! The answer is in the brackets the end of the value! Windows 2008 have moved the PCI, device and function values in a bracket

@system32\drivers\pci.sys,#65536;PCI bus %1, device %2, function %3;(3,0,0)

So in this case, the values are PCI bus 3, device 0, function 0.

Now all I have to do is to change my script logic to grab the values between the brackets instead for Windows 2008 servers.

No Comments Yet »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.