Using NETSTAT to determine the default NIC

rated by 0 users
This post has 6 Replies | 2 Followers

Top 150 Contributor
Posts 14
VernAnderson Posted: 11-07-2011 2:08 PM

Hello Don,

First thank you for all of the awesome tips, the book, and the training videos.

I am a Windows Systems Administrator in a very large environment. We have multiple network Interfaces in most of our customer’s servers and we access our customer’s servers through a NATed public IP. The servers also have a "Backup" network that is dedicated to backing up to tape.  The backup NICs are usually on a 10.x.x.x network but not always.

I want my Powershell tools to be able to do things with their private IP and I have been trying to think of a crafty way of scripting the discovery of what that IP address is while remoting to the server over the public IP. One method I thought of would be that NETSTAT spits out a list that shows the open ports and connections. One column "Local Address" would have a larger number of instances of the "Local Address" column and therefore would be an easy way to rule out the secondary NIC or backup networks IPs.

Is there a way to pipe the output of NETSH into Powershell and have it count the number of IPs in the "Local Address" column of the output and thereby output the one that had the most hits? All while in an "Enter-PSSession" remoting session?

1. Can I execute a NETSH in an "Enter-PSSession"   session?

2. How can I then take the output of that and count the number of the most instances of an IP and then use that logic to declare that I have discovered the "private" IP of this NATed server.

I have full remote admin access of the server but I connect using it's public NATed IP so the IP bound to the public NIZC is what I need to be able to query.

 -VERN

Top 150 Contributor
Posts 14

I guess I would also need to remove everything in that column after the  ( : ) colon character

Top 10 Contributor
Posts 640

You could query Win32_NetworkAdapterConfiguration from WMI. You'll obviously get all the bogus virtual adapters, but the IPAddress property on that class is actually an array, and it'll let every IP address configured on that NIC. 

Going your way, sure. You'd run the Netstat output through the -match, giving it a regex that looks like an IP address (something like \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} I guess). Get it to capture the matches, not just count them, and then run the matches through Select-String with -unique to filter out duplicates. 

But the WMI way sounds bazillions easier. On my system, this does it:

gwmi win32_networkadapterconfiguration | where { $_.ipenabled -ne $False } | select -expand ipaddress

The idea being that the fake-out adapters don't have IP enabled, usually. You might expand the filtering to just grab certain IPv4 addresses, or to filter on the adapter's name, or something else to just get that info. But the class is pretty flexible.

You could perhaps add cleverness to this approach. For example, if pinging a machine FROM THAT MACHINE will always return the IP you want, then this would do it:

test-connection ($env:computername) | select -expand ipv4address -first 1 | select -expand ipaddresstostring

That'd work to get the IP address the machine uses to communicate "internally." But the IP address you use to connect doesn't control what you can "see" once you're connected to the machine.

Again, these are all commands you'd run ON the remote machine WHILE remoted into it.

Hope some of that helps.

Top 150 Contributor
Posts 14

Thanks for your response, yea the "gwmi Win32_NetworkAdapterConfiguration" not only returns the 10.10.1.120 backup IP it also returns the IP I wanted but it's enclosed in { } curly brases.

I like your version of it though because it seems to have cleared the curly brases but when I tried it on one of the servers I get these results:

10.134.58.197
10.10.10.2
192.168.100.90
169.254.2.40
fe80::ad38:6b29:1e75:d5c8

So that is why I needed the logic to differentiate the "public" NIC which in this example would be the 192.168.100.90 but I need the code to figure that out. Which is why I thought of the NETSTAT command and counting the number of rows the majority one should be the public NIC in most cases I hope. I will try your examples here...Thanks again!

-VERN

Top 10 Contributor
Posts 640

{curlies} mean it's a collection of 1+ values; Select-Object's -expand parameter extracts the contents of a collection.

Given that you already know which public IP you're using, you should be able to eliminate that pretty easily. You said you were using removing, right?

Invoke-Command -computername whatever -scriptblock { $known = $_; Get-WmiObject -class Win32_NetworkAdapterConfiguration | Where { $_.ipenabled -ne $False } | Select -expand ipaddress | where { $_ -ne '192.168.100.90' }}

So you'd run that on YORU computer, to connect to computer "whatever," having public IP 192.168.100.90. That computer will retrieve all of its IP addresses, and filter out the one you know is public. You can obviously ping it from your end to get the public address, so with a couple of commands in a little script file, you should be able to pull it off.

Anytime you're parsing through a wedge of text, you're not really letting PowerShell work its strengths.

 

function Get-NonPublicIP ($computername) {

$known = Test-Connection $computername -count 1 | select -expand ipv4address | select -expand ipaddresstostring

Invoke-Command -computername $computername -scriptblock { Get-WmiObject -class Win32_NetworkAdapterConfiguration | Where { $_.ipenabled -ne $False } | Select -expand ipaddress } | where { $_ -ne $known }

}

Get-NonPublicIP SERVER2

 

Something like that. I'm not in front of a shell at the moment, but that should be darn close.

Top 150 Contributor
Posts 14

Well this is a great lesson on the curly braces then. That is good to know.

Sorry for not being totally clear, what I meant in my statement was I can tell that the 192 is the one I am looking for but I meant that by human deduction I can tell that's the private IP of the public network interface.

Other customers might get a 192.168 block while others may have a 172.16 block, and other whacky customers might be using 10.10.x.x for they public net and so you can not always rely on a match on a 192.

So my thoughts were that I would generate a ping to a public address such as yahoo.com (ping -n 50 yahoo.com) while that's running it should generate a lof of port 80 connections on whichever NIC is routing traffic to the Internet. Then based upon the list that NETSTAT  generates the IP address with the most connections would have more rows in the output of the NETSTAT -n command.

Then I want to use that output based upon the logic that the IP address that appears on more rows is the internet connected IP address. And from that result put just the IP address into a variable for later use in a script.

Sorry for not being more clear we have an interesting setup that presents us Administrators with many challenges. It is a complicated network no doubt.

 

Here is some things I came up with so far, one idea was sending NETSTATs output to a text file and then...

Get-Content .\netstat.txt | Sort-Object "Local Address" -Descending | Select-Object -First 1

But it needs more testing, because the "Local Address" column is not really a "-Property" the descending output doesn't seem to be reliable. But so far this little command string has output the correct answer on 3 servers I have tried it on.

 

As we type I'm learning about the get-content and set-content and am using it to try to "GREP" the netstat.txt into something with less junk in it like the first line that reads "Active Connections" is not needed. I am not giving up but am always open to other methods. The usual scripts like in the "Hey IT Scripting guy" archives don't work in my environment because they all rely on DNS and for me DNS resolves the NAT IP and not the true IP in the TCP/IP settings on the remote server.

-VERN

Top 150 Contributor
Posts 14

hmmm

 just found this on one of your favorite sites...

 

http://poshcode.org/560

Page 1 of 1 (7 items) | RSS
Copyright 2012 PowerShell.com. All rights reserved.