Check NIC bind order
Using the wrong bind order for multihomed servers can cause serious problems. Applications not working, network segments flooded with unneccesary traffic and even security leaks are some of the dangers.
That’s why I’ve created a Powershell script that checks all your servers for you. Let me explain how it works:
The binding order is store in the following registry key:
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage
It contains a multi-string value Bind such as this one:
DeviceNetBT_Tcpip_{A0344E82-4E65-47A2-92FF-B3183A181473}
DeviceNetBT_Tcpip_{C34D5A39-DA8D-4D58-82D4-099098D5501C}
What we are interested in, is to identify each TCP/IP interface in this list. We can identify them by correlating the identifier (or key) between the curly brackets {} to an IP address. We find all relevant information in the following registry key:
SYSTEMCurrentControlSetServicesTcpipParametersInterfaces
It contains subkeys named after the identifiers of the different TCP/IP interfaces, with a multi-string value IPAddress which contains the IP addresses set on this interface.
So let’s read the second collection of registry keys and values first, and create a collection of objects representing the interfaces, having properties representing the identifier and the IP address:
$registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $serverName) # Open remote HKLM key
$baseKey2 = $registry.OpenSubKey(“SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces”)
$myCol = @()
$NICS = $baseKey2.GetSubKeyNames() # Set of interfaces
ForEach ($NIC in $NICS)
{
$myObj = “” | Select-Object Key, IP # Create object for relation between identifier and IP address
$key = $baseKey2.OpenSubKey(“$NIC”)
$myObj.Key = $key.name.split(“{“)[1].trimend(“}”) # Get identifier of interface without brackets
$myObj.IP = $key.GetValue(“IPAddress”) # Get IP address of interface
$myCol += $myObj # Create collection of interface objects
}
Nice. Now we have the $myCol variable holding a collection of objects like so:
PS D:Scripts> $myCol
Key IP
— –
1B68A2DD-B093-4E12-A347-CED975434F12 {0.0.0.0}
313D4DA6-B0A6-41B6-B34D-97C89A3E0D65 {10.2.0.112}
A0344E82-4E65-47A2-92FF-B3183A181473 {10.1.0.112}
C34D5A39-DA8D-4D58-82D4-099098D5501C {0.0.0.0}
Now let’s read the binding order:
$baseKey1 = $registry.OpenSubKey(“SYSTEM\CurrentControlSet\Services\Tcpip\linkage”)
$bindorder = $baseKey1.GetValue(“Bind”)
That’s easy! Now to match the correct IP address to the second object in the $bindorder array:
$wantedboundkey = $bindorder[$index].split(“{“)[1].trimend(“}”) # Get identifier of …th TCP/IP interface in binding order
$wantedbound = $myCol | Where {$_.Key -eq $firstboundkey} # Find matching interface in collection
$wantedbound.IP # Return matching IP address
And there you have it!
PS D:Scripts>$wantedbound.IP
10.2.0.112
Below is the entire script that queries Active Directory for computers and runs the above script (defined as a function).
You should be able to figure out how it works.
Enjoy!
$outputFile = “D:Scriptsoutput.txt” # Default output path
function Get-BoundIP
{
param([string]$serverName, [Int]$index)
$registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, $serverName) # Open remote HKLM key
If ($registry)
{
$baseKey1 = $registry.OpenSubKey(“SYSTEM\CurrentControlSet\Services\Tcpip\linkage”)
$bindorder = $baseKey1.GetValue(“Bind”)
$baseKey2 = $registry.OpenSubKey(“SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces”)
$myCol = @()
$NICS = $baseKey2.GetSubKeyNames() # Set of interfaces
ForEach ($NIC in $NICS)
{
$myObj = “” | Select-Object Key, IP # Create object for relation between identifier and IP address
$key = $baseKey2.OpenSubKey(“$NIC”)
$myObj.Key = $key.name.split(“{“)[1].trimend(“}”) # Get identifier of interface
$myObj.IP = $key.GetValue(“IPAddress”) # Get IP address of interface
$myCol += $myObj # Create collection of interface objects
}
$wantedboundkey = $bindorder[$index].split(“{“)[1].trimend(“}”) # Get identifier of …th interface in binding order
$wantedbound = $myCol | Where {$_.Key -eq $wantedboundkey} # Find matching interface in collection
$wantedbound.IP # Return matching IP address
}
}
Write-Host “Grabbing server names …”
$servers = Get-QADComputer -SizeLimit 0 -SearchRoot “OU=Servers,DC=example,DC=com” | Sort-Object Name # Get all servers from AD
$myCollection = @()
ForEach ($server in $servers)
{
Write-Host “Processing server” $server.name
$myObject = “” | Select-Object Name, FirstIP, SecondIP # Create object for output organization
$myObject.Name = $server.name # Set server name
$myObject.FirstIP = Get-BoundIP $server.name 0 # Run function to get first bound IP address
$myObject.SecondIP = Get-BoundIP $server.name 1
$myCollection += $myObject # Build collection of objects
}
$output = $myCollection | Format-Table -AutoSize # Format output
# Create output
If ((Test-Path $outputFile) -eq $False) # If the output file does not exist
{
Write-Host “Creating output file …”
$creatingOutputFile = New-Item $outputFile -ItemType File # Create output file
}
Write-Host “Writing output to file …”
$output | Out-File -FilePath $outputFile -Force # Output file is overwritten with new output
Write-Host “Launching output file ($outputFile) …”
Invoke-Item $outputFile
No related posts.
11 Responses to Check NIC bind order
Tags
Active Directory API bind order cleanup cluster CPU Custom Fields datastores description device management directory tree errors Event Log file name filter Fun function HA IT known issues License Server LUN multipath NIC objects Oneliner portgroups PowerCLI PowerShell profile recursive Registry Scripts security session share snapshots SQL Stat VI Toolkit VMware vSphere WMI WSUS ZenArchives
- July 2012
- July 2011
- February 2011
- January 2011
- December 2010
- May 2010
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008





[...] http://www.peetersonline.nl/index.php/powershell/check-nic-bind-order [...]
Hi,
Just small detail, but as the Trim method does accept more then one character, this method of removing the curly braces might be a bit more clear
$key.name.trim(‘{}’)
Enjoy,
Groeten //o//
I see this script gives a listing of the bind orders, but is it possible to modify the script to automatically change the binding order of the interfaces?
Hi:
This is a great script. Thank you very much.
One improvement to take care of conditions where some servers have one NIC and another has two is to initialize the variable after each iteration:
$myObject.FirstIP = “”
$myObject.SecondIP = “”
after your statement:
$myObject = “” | Select-Object Name, FirstIP, SecondIP
Nice script, did you notice that all backslashes appear as interpreted, when you read your post? c:\path becomes c:path and and SYSTEM\CurrentControlSet becomes SYSTEMCurrentControlSet.
This script will not produce accurate results in some cases.
The Bind list is ordered without account for whether the interface is active/assigned IP or a virtual/loopback adapter.
Best to get the Bind values and then compare them against a WMI query that filters out the loopback adapters (servicename = msloop), ipenabled != ‘false’ and those without IP’s (ipaddress != 0.0.0.0).
Using the WMI query as validation for the Bind list pulling out the first valid Bind entry.
That’s what I’m rolling in to prod anyway since it’s accurate, but thanks for showing the path.
[...] network bindings. How are you going to achieve that then? You could use the procedure as mentioned here. However, you could also use the tool available here. This tool was created by a Microsoft [...]
Hello,
I just want to say that you can check binding order through command “ipconfig /all” and in which order NICs are same binding order these NICs have.
[...] Now imagine, you are using the other available installation option, also known as Server Core. As you may know, Server Core does not provide, that does not provide a GUI such as the Network Connections Control Panel to change network bindings. How are you going to achieve that then? You could use the procedure as mentioned here. [...]
Hi PeetersOnline,
I tried the BIND order script but when I try to create this variable:
$wantedboundkey = $bindorder[$index].split(“{“)[1].trimend(“}”)
I receive error:
PS C:\Users\larryh> $wantedboundkey = $bindorder[$index].split(“{“)[1].trimend(“}”) # Get identifier of .
th TCP/IP interface in binding order
Index operation failed; the array index evaluated to null.
At line:1 char:30
+ $wantedboundkey = $bindorder[ <<<< $index].split("{")[1].trimend("}") # Get identifier of .th TCP/IP interfac
e in binding order
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : NullArrayIndex
Can you take a look?
Oops, I see now the slashes in SYSTEMCurrentControlSetServicesTcpiplinkage disappeared in the post. I’ll try to fix the post.
Hugo