Most IT professionals regularly deal with networks and network management.
PowerShell includes several network-related cmdlets, such as Test-Connection, Test-NetConnection, and Resolve-DnsName. However, these cmdlets are often slow and resource-intensive, and they all lack support for configurable timeouts. When you need to ping or test ports on multiple servers, you either run out of resources, wait many seconds for each non-responding computer, or both.
This is why we chose the topic “Networking Tools”—to demonstrate how you can easily extend PowerShell with new, more powerful cmdlets of your own.
We start with the most widely used functionality: pinging computers via ICMP requests.
Test-Connection
Test-Connection can be used to ping computers, but it does not scale well. If you try to ping more than one computer—such as an IP range or a list of servers—it often takes a long time, and the cmdlet may even run out of resources.
In this example, the IP range from 192.168.2.1 to 192.168.2.254 is checked:
1..254 | ForEach-Object { "192.168.2.$_" } | ForEach-Object {
Test-Connection -ComputerName $_ -Count 1
} In Windows PowerShell, the script stops after the first successful ping:
Source Destination IPV4Address IPV6Address Bytes Time(ms)
------ ----------- ----------- ----------- ----- --------
DELL7390 192.168.2.1 192.168.2.1 32 1
Test-Connection : Testing connection to computer '192.168.2.2' failed: Error due to lack of resources
In PowerShell 7, error messages no longer appear, but the results are still slow and presented in a format that isn’t very useful.
Test-NetConnection
Test-NetConnection is a sophisticated network testing tool that can also be used for pinging.
However, it takes even longer to run, and it emits warnings only for non-responding computers—so they do not appear in the results:
1..254 | ForEach-Object { "192.168.2.$_" } | ForEach-Object {
Test-NetConnection -ComputerName $_
} Simple and Fast Ping Command
If you just want to scan an IP range or a list of servers and receive a simple list of results, the best approach is to call .NET methods directly and create your own function:
function Ping-Computer
{
param
(
[Parameter(ValueFromPipeline,Mandatory)]
[string]
$ComputerName,
# timeout in milliseconds
[int]
$Timeout = 5000
)
begin
{
$obj = [System.Net.NetworkInformation.Ping]::new()
}
process
{
$obj.Send($ComputerName, $timeout) |
Select-Object -Property Status, Address, RoundTripTime, Success |
ForEach-Object {
# fill in the computer name/IP address in case there was
# no response
$_.Address = $ComputerName
# add a boolean value
$_.Success = $_.Status -eq [System.Net.NetworkInformation.IPStatus]::Success
$_
}
}
end
{
$obj.Dispose()
}
}
Ping-Computer is much faster and easier to use. Since it supports pipeline input, you can pass in all the server names or IP addresses. With its -Timeout parameter, you can control how long to wait before considering an address non-responsive. This way, you avoid wasting excessive time on non-responding addresses.
1..254 | ForEach-Object { "192.168.2.$_" } | Ping-Computer -Timeout 1000 It generates an easy-to-read list of results:
Status Address RoundtripTime Success
------ ------- ------------- -------
Success 192.168.2.1 0 True
TimedOut 192.168.2.2 0 False
Success 192.168.2.3 0 True
Success 192.168.2.4 0 True
...
You can also read the server names from a text file:You can also read the server names from a text file:
Get-Content -Path c:\data\serverlist.txt | Ping-Computer -Timeout 1000 You can also use the new command in everyday routines to quickly ping an address:
PS C:\> Ping-Computer microsoft.com
Status Address RoundtripTime Success
------ ------- ------------- -------
Success microsoft.com 14 TrueRelated links
- ScriptRunner ActionPacks will help you automate tasks
- Try out ScriptRunner here
- ScriptRunner: Book a demo with our product experts

