The built-in cmdlet Test-NetConnection can test ports; however, it is complex to use and slow:
1..254 | ForEach-Object { "192.168.2.$_" } | ForEach-Object {
Test-NetConnection -Port 445 -ComputerName $_
}The cmdlet is especially slow for any address that isn’t responding because it uses a relatively long timeout value that cannot be changed.
A better Port Scanning Tool
If you just want to test a port on an IP range or a list of servers, using .NET directly and creating your own function is a far more efficient approach:
function Test-Port
{
[CmdletBinding(DefaultParameterSetName='multipleComputers')]
param
(
[Parameter(Mandatory, Position=1, ParameterSetName='multiplePorts')]
[Parameter(Mandatory, ValueFromPipeline, Position=0, ParameterSetName='multipleComputers')]
[string]
$ComputerName,
[Parameter(Mandatory, Position=1, ParameterSetName='multipleComputers')]
[Parameter(Mandatory, ValueFromPipeline, Position=0, ParameterSetName='multiplePorts')]
[int]
[ValidateRange(1,65535)]
$Port,
[int]
[ValidateRange(100,100000)]
$TimeoutMilliSec = 1000
)
begin
{
}
process
{
try
{
$client = [System.Net.Sockets.TcpClient]::new()
$task = $client.ConnectAsync($ComputerName, $Port)
if ($task.Wait($TimeoutMilliSec))
{
$success = $client.Connected
}
else
{
$success = $false
}
}
catch
{
$success = $false
}
finally
{
$client.Close()
$client.Dispose()
[PSCustomObject]@{
ComputerName = $ComputerName
Port = $Port
Success = $success
}
}
}
} You can now quickly test a port on an individual server:
PS C:\> Test-Port -Port 445 -ComputerName $env:COMPUTERNAME
ComputerName Port Success
------------ ---- -------
DELL7390 445 True
PS C:\> Test-Port -Port 80 -ComputerName microsoft.com
ComputerName Port Success
------------ ---- -------
microsoft.com 80 True However, you can now test entire server lists or IP ranges as well. Thanks to the configurable timeout, this is much faster than before. The following line finds all computers in the specified IP range that have SMB enabled—including those with ICMP/ping disabled:
1..254 | ForEach-Object { "192.168.2.$_" } | Test-Port -Port 445 Similarly, if you want to find network printers, use port 9100 instead. This line returns all printers and ignores any non-responding addresses:
1..254 | ForEach-Object { "192.168.2.$_" } | Test-Port -Port 9100 | Where-Object Success You can even pipe in a range of port numbers instead of IP addresses or server names. Test-Port automatically selects the appropriate parameter set and tests the range of ports on a single computer:
PS C:\> 80, 445, 5985, 5986 | Test-Port -Computername $env:computername
ComputerName Port Success
------------ ---- -------
DELL7390 80 False
DELL7390 445 True
DELL7390 5985 True
DELL7390 5986 True Related links
- ScriptRunner ActionPacks will help you automate tasks
- Try out ScriptRunner here
- ScriptRunner: Book a demo with our product experts

