Powershell

Update @ 3:58 pm: At risk of losing the one-liner nomenclature at a very worthwhile increase in speed, read below.

The One-Liner WMI Version

One-liner to retrieve the first IP address of the first adapter which has a default gateway set. This is a very reliable, yet not perfect technique for determining the "right" IP address. It will work well in all but the most complex of network configuration scenarios.

@( Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object { $_.DefaultIpGateway } )[0].IPAddress[0]

Note that I have used the @() array notation around the Get-WmiObject call so that I don’t have to worry about how many network adapters come back. If only one comes back, I have an array with one item. If I didn’t do this, then I would have to do an if statement to check whether it’s an array (meaning that the system has multiple NICs with default gateways—which is super-rare but possible).

The .NET Class Method

It’s no longer a single line, but honestly, length is not a measure of quality in scripting. I noticed that the above WMI call was noticeably sluggish. Measurements with Measure-Command cmdlet showed an average execution time of 455 milliseconds. Here’s a different way using the Net.NetworkInformation.NetworkInterface .NET class.

$allNIC = [system.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces()

$PrimaryNIC = $allNIC | Where-Object { $_.GetIPProperties().GatewayAddresses }

$PrimaryNIC.GetIPProperties().UnicastAddresses[0].Address.IPAddressToString

New time averages 13 milliseconds on my system. That’s a huge difference which I was not surprised to see based on past experience.

: http://halr9000.com/article/829

2009-10-09 22:20:29

You could keep it as a oneliner ;)

PS>[system.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() |
Where-Object {$_.GetIPProperties().GatewayAddresses} |
ForEach-Object {$_.GetIPProperties().UnicastAddresses|
Foreach-object{$_.Address.IPAddressToString}
}

I added the second foreach loop b/c my systems have both an IPv4 & IPv6 address

~Glenn

Brad Ascar
2009-10-14 07:16:12

I ran into an issue with the .NET part. The first example runs fine for me, but on 2 different systems I have I got the following when running the second method:

Method invocation failed because [System.Object[]] doesn’t contain a method named ‘GetIPProperties’.
At :line:3 char:27
+ $PrimaryNIC.GetIPProperties <<<< ().UnicastAddresses[0].Address.IPAddressToString

if I replace your last line with:

foreach ($nic in $PrimaryNIC){
$nic.GetIPProperties()
}

I get:

Object reference not set to an instance of an object.
At :line:0 char:0

I have attempted some debugging of my own but have run to the end of my knowledge of PowerShell.

2009-10-14 07:54:46

Brad, Glenn’s version doesn’t work? I suspect that you’ve got IPV6 enabled, right?

Brad Ascar
2009-10-14 08:21:15

No IPV6 configured and no output from Glenn’s script.

  • Microblog

  • Recent Posts

  • Recent Comments

  • meta

  • PowerShell Blogroll