Monday, August 9, 2010

Getting the NIC card binding order

I was playing around with some ideas today for identifying what is the primary NIC card of a Windows system, so I could add that to some Dns client setting monitoring I'm working on. The problem of NIC bindings has come up in the past during some troubleshooting on servers that were plugging into trunk ports and had a lot of virtual nic's for different subnets. For those that do no know about binding order, when you are in windows, on the network properties page (for newer OS versions that is "Change adapter settings"). There is a menu item, though it may be hidden to make your life more difficult in new OS's. Try alt-N to pull up the network Advanced menu, and select "Advanced Settings". In this dialog box, you will see a list of connections available and their order. You can move NIC's up and down to set what is the primary NIC for a system. On some Os's this requires reboot to take effect. The binding order is stored in the registry under HKLM\System\CurrentControlSet\Services\TcpIP\Linkage key with a multistring value called Bind. This lists devices by GUID. You can match up the guid values here to the interfaces in other registry locations, or read them through WMI. The reason NIC binding can be important can include, selection of default gateway (windows only supports 1 at a time), and determining what interface traffic originating from the machine uses. In the case of my previously mentioned problems, the problem was DNS lookups were going out the wrong interface, into a secluded subnet to DNS servers that could not reply back due to firewall restrictions. Moving the order will allow you to control what NIC is your source IP. In any case, I though it would be useful to throw together a basic script to list out the binding order of multihomed machines. This script returns an array of PSObjects with the following: BindingOrder, Description, GUID, IP, SubnetMask, Gateway; where description is the text value that shows up in your list of network adapters, and GUID is what is used to reference it in the registry.
#get-binding order
#Check a remote machine to see NIC binding order.

$server = $args[0]

if ($server -eq $null -or $server -match "\?") {
 Write-Host -ForegroundColor "yellow" "Usage:  Get-NicOrder "
 Write-Host -ForegroundColor "yellow" "    Enter the name of a system to connect to.  This script will"
 Write-Host -ForegroundColor "yellow" "    provide the network card binding order of a remote machine."
 exit
}

$key = "System\CurrentControlSet\Services\Tcpip\Linkage"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$regkey = [Microsoft.win32.registrykey]::OpenRemoteBaseKey($type,$server)

if (-not $?) {
 Write-Host -ForegroundColor "red"  "Cannot check remote machine, exiting...."
 exit
}

$regkey = $regkey.opensubkey($key)
$ArrBindingGUIDs = $regkey.getvalue("Bind")
 
$ArrNicList = Get-WmiObject -ComputerName $server -Query "select Description,settingid,ipaddress,ipsubnet,defaultipgateway from win32_networkadapterconfiguration"

$ArrResults = New-Object collections.ArrayList

for ($i = 0; $i -lt $ArrBindingGUIDs.length; $i++) {
    if ($arrbindingguids[$i].contains("{") {
  $guid = $ArrBindingGUIDS[$i].substring($ArrBindingGUIDs[$i].indexof('{'))
  foreach ($nic in $ArrNicList) {
   if ($nic.settingid -eq $guid) {
    $result = New-Object psobject
    Add-Member -InputObject $result NoteProperty BindingOrder $i
    Add-Member -InputObject $result NoteProperty Description $nic.Description
    Add-Member -InputObject $result NoteProperty GUID $nic.SettingID
    Add-Member -InputObject $result NoteProperty IP $nic.ipAddress
    Add-Member -InputObject $result NoteProperty SubnetMask $nic.ipsubnet
    Add-Member -InputObject $result NoteProperty Gateway $nic.defaultIpGateway
    $Arrresults.add($result) >$null 
   }
  }
 }
}

Return $arrResults
 

No comments:

Post a Comment