PowerShell Check Open Ports with Test-NetConnection

PowerShell Check Open Ports with Test-NetConnection

PowerShell Tips Editor 4 min read
PowerShell Check Open Ports with Test-NetConnection

Before deploying a service or opening a firewall rule, you need to confirm that a specific TCP port is actually reachable — and you’d rather not install nmap on a production server. PowerShell check open ports is straightforward with Test-NetConnection: it tests a TCP handshake against any port you specify, returning a clean object that tells you whether the port accepted the connection, was refused, or was silently dropped. No third-party tools, no guesswork.

Test a Single Port

Test-NetConnection with the -Port parameter performs a TCP connection attempt. The TcpTestSucceeded property in the result is the definitive answer — $true means the port is open and the service accepted the connection.

Test-NetConnection -ComputerName "server01" -Port 443
ComputerName     : server01
RemoteAddress    : 10.0.0.5
RemotePort       : 443
InterfaceAlias   : Ethernet
SourceAddress    : 10.0.0.2
TcpTestSucceeded : True

Extract just the Boolean for use in scripts:

$result = Test-NetConnection -ComputerName "server01" -Port 443
if ($result.TcpTestSucceeded) {
    Write-Output "Port 443 is open"
} else {
    Write-Output "Port 443 is blocked or closed"
}

Check Multiple Ports with ForEach

Scanning several ports on the same host is a common troubleshooting step — for example, verifying that a web server is listening on both 80 and 443, and that the database port is not accidentally exposed.

$host   = "server01"
$ports  = @(80, 443, 3389, 1433, 22)

$results = foreach ($port in $ports) {
    $test = Test-NetConnection -ComputerName $host -Port $port -WarningAction SilentlyContinue
    [PSCustomObject]@{
        Host   = $host
        Port   = $port
        Open   = $test.TcpTestSucceeded
    }
}

$results | Format-Table -AutoSize
Host      Port  Open
----      ----  ----
server01  80    True
server01  443   True
server01  3389  False
server01  1433  False
server01  22    True

Verbose Mode for Traceroute

Adding -InformationLevel Detailed (or the older -TraceRoute switch) provides hop-by-hop path information, similar to tracert.exe. This helps you identify where traffic is being dropped — at the firewall, a router, or the target host itself.

Test-NetConnection -ComputerName "8.8.8.8" -TraceRoute

Scan Common Ports on a Server

Build a quick security audit by scanning a defined set of known service ports across one or more servers. Pipe the results to a CSV for a point-in-time record.

$commonPorts = @{
    "HTTP"   = 80
    "HTTPS"  = 443
    "RDP"    = 3389
    "SMB"    = 445
    "SSH"    = 22
    "SQL"    = 1433
    "SMTP"   = 25
}

$servers = @("server01", "server02")

$report = foreach ($server in $servers) {
    foreach ($service in $commonPorts.GetEnumerator()) {
        $test = Test-NetConnection -ComputerName $server -Port $service.Value `
                    -WarningAction SilentlyContinue
        [PSCustomObject]@{
            Server  = $server
            Service = $service.Key
            Port    = $service.Value
            Open    = $test.TcpTestSucceeded
        }
    }
}

$report | Export-Csv -Path "C:\Logs\portscan-$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation

Detect Firewall Blocks vs Closed Service

There is an important distinction between a port that is blocked by a firewall and one that the OS is actively refusing because no service is listening. A firewall drop results in a timeout — TcpTestSucceeded is $false and the command takes the full timeout to return. A refused connection (RST packet) returns immediately with $false. You can detect the difference by measuring elapsed time.

$start  = Get-Date
$result = Test-NetConnection -ComputerName "server01" -Port 8080 -WarningAction SilentlyContinue
$elapsed = (Get-Date) - $start

if (-not $result.TcpTestSucceeded) {
    if ($elapsed.TotalSeconds -gt 5) {
        Write-Output "Port 8080 appears FIREWALL BLOCKED (timeout after $([int]$elapsed.TotalSeconds)s)"
    } else {
        Write-Output "Port 8080 is CLOSED (service not running)"
    }
}

Export Port Scan Results

The multi-server, multi-port scan from the earlier section already demonstrates Export-Csv. For large scans, add -WarningAction SilentlyContinue to suppress the flood of warning messages when ports are closed, keeping your output clean.

Common Errors and Fixes

  • TcpTestSucceeded false vs no route: A result of $false can mean the port is closed, the host is unreachable, or a firewall is dropping packets. If PingSucceeded is also $false, the host may be unreachable entirely — check ICMP with Test-Connection first to rule that out before concluding the port is blocked.
  • UDP ports not supported: Test-NetConnection only supports TCP. UDP port testing is not natively available in PowerShell without using .NET sockets directly. For UDP services like DNS (port 53) or SNMP (port 161), use Resolve-DnsName or specialized tooling to verify service availability.

Related Cmdlets / See Also

Wrapping Up

Test-NetConnection is your no-install port scanner for Windows — fast, object-based, and native to every modern Windows system. As a next step, schedule the common-ports scan above to run weekly and diff the results against a baseline file so you get automatic alerts when new ports appear open on your servers.

Send-Item -To