Monday, May 25, 2015

Moving from ping, netstat and ipconfig to Powershell

Ping, Netstat and Ipconfig are the three major legacy commands that every Windows system administrator out there has been using for decades and that, I bet, most of you are still using pretty often notwithstanding the large spread of Powershell. Well, I am not telling you to switch to Powershell today for performing basic tasks like pinging hosts or clearing your DNS cache. I am just going to show you the cmdlets that in Powershell do these tasks. And, knowing the fact that Powershell is an object-based language with a strong pipeline support, you imagine that using the Powershell way is a better option and gives you a flexible syntax as wel as re-usable results.


Let's start from the first legacy command. While working in a research laboratory, back in 1983, in just one evening, Mike Muuss wrote the ancestor of the small utility that everyone of us knows as being the first tool to use to check network connectivity: ping.exe.

Microsoft came up a great amount of years later with a new cmdlet that leverages ICMP for its second version of Powershell: Test-Connection.

Test-Connection is based on the Win32_PingStatus class and since Powershell 3.0 supports a -Source parameter, which makes the use of this cmdlet particularly interesting over the use of old style pings. In fact, the -Source parameter allows you to specify the names of the computer where the ping originates from:

Test-Connection -Source Src01, Src02, Src03 -ComputerName Dst01
Also, Test-Connection allows you to ping multiple hosts at once:

Test-Connection -ComputerName Dst01, Dst02, Dst03
Using Test-Connection instead of ping allows you to take advantage of the $? variable to perform conditional actions:

if(Test-Connection nonexistingserver){'succeded'}else{'Failed'}
Test-Connection : Testing connection to computer 'nonexistingserver' failed: No such host is known
At line:1 char:4
+ if(Test-Connection nonexistingserver){'succeded'}else{'Failed'}
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ResourceUnavailable: (nonexistingserver:String) [Test-Connection], PingException
+ FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand
if(Test-Connection -ComputerName Server01 -Quiet){New-PSSession Server01}
This variable is not available for legacy commands (as I explained in this previous post), so the value of $? stays $True when you use legacy ping, and this is a limiting factor in using ping.exe in conditional statements:

if(ping nonexistingserver){'succeded'}else{'Failed'}
So now, if you are decided to replace the ping command with Test-Connection, you can simply create an alias named 'Ping' and you're set:

Set-Alias ping Test-Connection
or if you want a quicker way, just name the alias 'p':

Set-Alias p Test-Connection

The second command I want to talk of is ipconfig, which is the command used primarly to output your computer network configuration. This command was introduced 20 years ago, in 1995-1996, to Windows 95, at a time when putting the IP stack on everyone's PC was the main task of administrators and this involved typing arcane IPv4 numbers into the now forgotten winipcfg, which was in turn created for Windows 3.1 years before (remember the Wolverine stack?).

Ipconfig has four major switches as old as dinosaurs: /all, /flushdns, /displaydns and /registerdns. All of them have corresponding Powershell cmdlets, which I must admit makes them hard to remember. In any case working with network adapters has taken a great swing starting with Windows 8 and Windows 2012, when a new wave of network-oriented cmdlets belonging to the NetTCPIP module has appeared along with the underlying CIM namespaces and classes.

Ipconfig /all can be replaced by Get-NetIPConfiguration. Tough their output is more or less the same, a few consideration can be made about the improvement the Powershell cmdlet has brought to its predecessor. First of all, Get-NetIPConfiguration has switches for querying remote hosts: -Computername and -Cimsession.

You could for instance create a CIM session to pass to Get-NetIPConfiguration, even do for the moment the -CimSession switch of this cmdlet does not accept an array of computers:

$cimsession = New-CIMsession -Computername srv01

Get-NetIPConfiguration -CimSession $cimsession
Now, since Get-NetIPConfiguration returns an object, you could retrieve just one or more properties:

$ipconf = Get-NetIPConfiguration

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
Wi-Fi                                4 IPv6    {}
Wi-Fi                                4 IPv4    {,}
Bluetooth Network Connection         8 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff:...
Bluetooth Network Connection         8 IPv4    {}
Ethernet                             3 IPv6    {}
Ethernet                             3 IPv4    {}
Powerful, isn't it?

Now, for the lazy admin, know that the NetTCPIP module exports an alias for Get-NetIPConfiguration: gip. And since gip is way shorter than ipconfig, you have no reasons left to stick with the old command.

Ipconfig /flushdns can be replaced by Clear-DnsClientCache. This cmdlet purges the cache the client-side DNS cache that Windows stores on your computers.

The equivalent of Ipconfig /RegisterDns is Register-DnsClient. As its predecessor, Register-DnsClient invokes un update of the DNS names on all the interfaces of your computer.


The last command I'd like to talk about today is the old glorious netstat. I am a huge fan of this command since it saved me in many cases when working on network connectivity issues with firewalls and application ports. Nonetheless the time has arrived to explore the Powershell way of implementing the same functions.

Netstat -a, which is used to display connections and listening ports, has evolved toward Get-NetTCPConnection since Windows 2012 and Windows 8. The output is an object with six default fields:


LocalAddress                        LocalPort RemoteAddress                       RemotePort State       AppliedSetting
------------                        --------- -------------                       ---------- -----       --------------
::                                  49157     ::                                  0          Listen
::                                  49156     ::                                  0          Listen
::                                  49155     ::                                  0          Listen
::                                  49154     ::                                  0          Listen
::                                  49153     ::                                  0          Listen
::                                  49152     ::                                  0          Listen
::                                  445       ::                                  0          Listen
::                                  135       ::                                  0          Listen                        49465                      443        Established Internet                             49157                             0          Listen                             49156                             0          Listen                             49155                             0          Listen                             49154                             0          Listen                             49153                             0          Listen                             49152                             0          Listen                             135                             0          Listen
The greatest strength of Get-NetTCPConnection over netstat is the possibility to filter on connection state on the fly:

Get-NetTCPConnection -State Established

LocalAddress     LocalPort RemoteAddress        RemotePort State       AppliedSetting
------------     --------- -------------        ---------- -----       --------------     49465       443        Established Internet
This means that you can easily filter down all connections which are in the state SYN_SENT, that is connections that are being blocked by a security firewall:

Get-NetTCPConnection -State SynSent
Get-NetTCPConnection : No MSFT_NetTCPConnection objects found with property 'State' equal to 'SynSent'.  Verify the
value of the property and retry.
At line:1 char:1
+ Get-NetTCPConnection -State SynSent
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (SynSent:State) [Get-NetTCPConnection], CimJobException
    + FullyQualifiedErrorId : CmdletizationQuery_NotFound_State,Get-NetTCPConnection
In the previous example, no connection is being blocked, so the big red error shown must be interpreted as a good news. Irony of IT.

For completeness, the possible connection states accepted by Get-NetTCPConnection are: Closed, Listen, SynSent, SynReceived, Established, FinWait1, FinWait2, CloseWait, Closing, LastAck, TimeWait and DeleteTCB.

There is another truly important switch for netstat that we are going to discuss to complete this blog post: -r. Using netstat with -r prints the routing table of your computer. The output you get is historically the same that you can get by using 'route print':

route print
Interface List
  8...e4 d5 3d fd 15 99 ......Bluetooth Device (Personal Area Network)
  4...64 27 37 32 22 d1 ......Broadcom 4313GN 802.11b/g/n 1x1 Wi-Fi Adapter 9a 74 56 e8 89 ......Realtek PCIe GBE Family Controller
  1...........................Software Loopback Interface 1
  6...00 00 00 00 00 00 00 e0 Teredo Tunneling Pseudo-Interface

IPv4 Route Table
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric         On-link    306         On-link    306         On-link    306         On-link    306         On-link    306
Persistent Routes:

IPv6 Route Table
Active Routes:
 If Metric Network Destination      Gateway
  1    306 ::1/128                  On-link
  1    306 ff00::/8                 On-link
Persistent Routes:
In Powershell the cmdlet to use to get this piece of information is Get-NetRoute. In the case of Get-NetRoute, the interesting feature to highlight is of course the possibility to sort routes by metric:

Get-NetRoute | Sort-Object RouteMetric

ifIndex DestinationPrefix             NextHop     RouteMetric  PolicyStore
------- -----------------             -------     -----------  -----------
4            0     ActiveStore
8       fe80::c5ee:f21f:1980:6b41/128 ::          256   ActiveStore
4       fe80::a820:ec8e:e0c5:b536/128 ::          256   ActiveStore
3       fe80::44ad:3bde:8351:1b7/128  ::          256   ActiveStore
1       ff00::/8                      ::          256   ActiveStore
4       ff00::/8                      ::          256   ActiveStore
8       ff00::/8                      ::          256   ActiveStore
3       ff00::/8                      ::          256   ActiveStore
6       2001::/32                     ::          256   ActiveStore
3       fe80::/64                     ::          256   ActiveStore
6       ::/0                          ::          256   ActiveStore
1       ::1/128                       ::          256   ActiveStore
6       fe80::/64                     ::          256   ActiveStore
6       fe80::ffff:ffff:fffe/128      ::          256   ActiveStore
8       fe80::/64                     ::          256   ActiveStore
4       fe80::/64                     ::          256   ActiveStore
4              256   ActiveStore
8              256   ActiveStore
3              256   ActiveStore
1       256   ActiveStore
4       256   ActiveStore
8       256   ActiveStore
3       256   ActiveStore
1              256   ActiveStore
1             256   ActiveStore
1              256   ActiveStore
6       ff00::/8                      ::          256   ActiveStore
1       256   ActiveStore
4         256   ActiveStore
4          256   ActiveStore
4           256    ActiveStore
I hope you learned something. It's time to reimagine ipconfig, ping and netstat, guys. Time to move to Powershell and become a faster, more powerful admin. A zillion of cmdlets (network-oriented or not) are waiting for you.

The pipeline is yours.

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...