Test Network Connectivity with PowerShell Test-Connection

PowerShell

In this article, I will show you how to test network connectivity between two endpoints using the PowerShell Test-Connection cmdlet.

PowerShell Test-Connection vs Ping

Since the first time computers were networked together, people have had to test their connections. Just like a dial tone that tells you the phone is ready to use, many IT pros want to make sure they have a remote connection before beginning their ‘call’. For IT pros, this has traditionally meant using the PING utility that has existed since forever. It still works, and you can even use it in PowerShell.

But when used in PowerShell, you get text output that’s hardly useful for scripting. So, let me give you some additional options.

Test-Connection is a wrapper for the Win32_PingStatus WMI class

The PING utility works by sending a special type of packet, an Internet Control Message Protocol echo request (ICMP), to a remote computer. Similar to the way a sonar pings another submarine, PING sends out a probe and waits for a response. The PowerShell equivalent is the Test-Connection cmdlet.

Test-Connection is actually a wrapper for the Win32_PingStatus WMI class, but it’s easier to use because it’s a cmdlet.

How to use PowerShell Test-Connect

All you need to do is specify a remote computer name or IP address. The assumption is that you are testing a connection to another computer in your domain.

Using the PowerShell Test-Connection cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)
Using the PowerShell Test-Connection cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)

Send out more or less ‘pings’ using the -Count parameter

By default, the cmdlet sends four pings, but you can send out more or less.

test-connection chi-core01 -Count 2

The output has been formatted for your viewing pleasure. If you pipe a connection result to Get-Member, then you’ll discover the actual property names.

test-connection chi-core01 -Count 1 | Select Address,IPv4Address,ResponseTime,BufferSize
Discovering property names for our test connection. (Image Credit: Jeff Hicks)
Discovering property names for our test connection. (Image Credit: Jeff Hicks)

Test connectivity to multiple computers

The cmdlet allows you to specify multiple computer names:

$computers = "chi-dc01","chi-dc02","chi-dc04"
test-connection $computers -Count 1 | Select Address,IPv4Address,ResponseTime,BufferSize
Specifying multiple computer names with the Test-Connection cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)
Specifying multiple computer names with the Test-Connection cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)

A less verbose response from Test-Connection using the -Quiet parameter

If you merely want to test a connection, then you should use the –Quiet parameter. Instead of response data, you get a simple true or false that indicates whether the computer responded to a ping request.

Using the Test-Connection cmdlet to test a connection with the -quiet parameter. (Image Credit: Jeff Hicks)
Using the Test-Connection cmdlet to test a connection with the -Quiet parameter. (Image Credit: Jeff Hicks)

Test network connectivity to all computers in the default Active Directory computers container

Here’s an example of where you might use the -Quiet parameter in a script with Get-AdComputer:

get-adcomputer -filter * -server chi-dc04 -SearchBase "CN=Computers,DC=Globomantics,DC=Local" |
Where { Test-Connection $_.name -count 1 -quiet } |
Select @{Name="Computername";Expression={$_.Name}}

This command is getting all computer accounts in the default computers container in Active Directory (AD) and pinging each name once. If the computer responds, PowerShell passes the ADComputer object down the pipeline, where I’m simply writing an object with a single property of Computername.

Related Article: Check out Error Handling With PowerShell Try Catch Blocks on Petri to add error handling to your PowerShell commands and scripts!

I could continue adding to the pipelined expression any cmdlet that accepts pipeline input by property name for Computername.
Or you might try something like this:

$computers = "chi-dc01","chi-dc02","chi-dc04","chi-app01","chi-core01","chi-fp01","chi-fp02"
$computers | group {test-connection -count 1 -ComputerName $_ -quiet}
Using the Group-Object cmdlet to organize results in Windows PowerShell. (Image Credit: Jeff Hicks)
Using the Group-Object cmdlet to organize results in Windows PowerShell. (Image Credit: Jeff Hicks)

Using the Group-Object cmdlet, I’ve organized my results based on whether they responded or not.

Using PowerShell’s Test-NetConnection cmdlet

The Test-NetConnection provides additional connection information.

The Test-NetConnection cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)
The Test-NetConnection cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)

Even better, it works with external hosts. Assuming that the host is configured to respond to pings, of course.

The Test-NetConnection cmdlet in PowerShell has failed because the host isn't configured to respond to pings. (Image Credit: Jeff Hicks)
The Test-NetConnection cmdlet in PowerShell has failed because the host isn’t configured to respond to pings. (Image Credit: Jeff Hicks)

Use Test-NetConnection to test connectivity to common ports

However, you can use this to test for connectivity to common ports.

test-netconnection petri.com -CommonTCPPort HTTP
Using the Test-NetConnection cmdlet in PowerShell to test for connectivity to common ports. (Image Credit: Jeff Hicks)
Using the Test-NetConnection cmdlet in PowerShell to test for connectivity to common ports. (Image Credit: Jeff Hicks)

You can test for SMB, HTTP,RDP, or a PING.

Using the Test-NetConnection cmdlet in PowerShell to test connectivity for RDP. (Image Credit: Jeff Hicks)
Using the Test-NetConnection cmdlet in PowerShell to test connectivity for RDP. (Image Credit: Jeff Hicks)

I also appreciate that I can do a trace route with this command:

Performing a trace route with the Test-NetConnection cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)
Performing a trace route with the Test-NetConnection cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)

This leaves me with this result:

The trace route was not successful. (Image Credit: Jeff Hicks)
The trace route was not successful. (Image Credit: Jeff Hicks)

Granted, this may not be the result I want, but clearly there are some devices along the way to Petri.com that won’t respond to ping requests.
Finally, this command also can be used for simple Boolean testing.

test-netconnection 172.16.10.100 -CommonTCPPort SMB -InformationLevel Quiet

I tested to see if my NAS server is available. Here’s another example: I want to see which servers do not have Remote Desktop enabled.

"chi-dc01","chi-dc02","chi-dc04" | where { -NOT (Test-Netconnection $_ -CommonTCPPort RDP -InformationLevel Quiet)}
Using the Test-NetConnection cmdlet in PowerShell to determine which servers that don't have Remote Desktop enabled. (Image Credit: Jeff Hicks)
Using the Test-NetConnection cmdlet in PowerShell to determine which servers that don’t have Remote Desktop enabled. (Image Credit: Jeff Hicks)

Using the Test-WSMan cmdlet to test connectivity for PowerShell Remoting

Most of the testing I’ve shown thus far involves ICMP pings, where the computer or firewall must be configured to allow. It is also possible that the network adapter will apply to a ping even though the operating system is hung. If you want to verify that the remote computer is ready for you, you can try using the Test-WSMan cmdlet.

By this point I am assuming you have deployed PowerShell to your servers and enabled PowerShell Remoting. If not, you are making your life much more difficult. This cmdlet will verify that you can connect with the WSMan protocol, which means you can take advantage of the CIM cmdlets and remoting cmdlets like Invoke-Command.

Using the Test-WSMan cmdlet in PowerShell. (Image Credit: Jeff Hicks)
Using the Test-WSMan cmdlet in PowerShell. (Image Credit: Jeff Hicks)

Here’s why this might be useful. The remote computer CHI-Win81 is up and running and replies to pings.

The command has failed. (Image Credit: Jeff Hicks)
The command has failed. (Image Credit: Jeff Hicks)

But when I try to do something with it, the command fails because the WinRM service is not running on the client. It would have been better to try testing first.

Testing with the Test-WSMan cmdlet. (Image Credit: Jeff Hicks)
Testing with the Test-WSMan cmdlet. (Image Credit: Jeff Hicks)

Unfortunately, Test-WSMan doesn’t have any parameters to provide a simple Boolean response.

As a result, I wrote a simple wrapper function.

Function Test-PSRemoting {
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory,HelpMessage = "Enter a computername",ValueFromPipeline)]
[ValidateNotNullorEmpty()]
[string]$Computername,
[System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty
)
Begin {
    Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"
} #begin
Process {
  Write-Verbose -Message "Testing $computername"
  Try {
    $r = Test-WSMan -ComputerName $Computername -Credential $Credential -Authentication Default -ErrorAction Stop
    $True
  }
  Catch {
    Write-Verbose $_.Exception.Message
    $False
  }
} #Process
End {
    Write-Verbose -Message "Ending $($MyInvocation.Mycommand)"
} #end
} #close function
Wrapper for PowerShell Test-WSMan
Wrapper for Test-WSMan (Image Credt: Jeff Hicks)

This command will give you a simple true or false result. If you use alternate credentials and get a false re-try with –Verbose so you can see the error message.

You now have a variety of testing tools that I encourage you to use if you are scripting a process that involves a large number of computers. As always be sure to read full help and examples for everything I’ve shown you.