cheat sheet
netstat
Display active TCP/UDP connections, listening ports, routing tables, interface statistics, and per-connection process IDs from the Windows command prompt.
netstat — Network Connections and Statistics
What it is
netstat (Network Statistics) is a built-in Windows command that reports the state of network connections and sockets. It can show active TCP connections, all listening ports (TCP and UDP), the process ID and executable behind each connection, interface-level statistics, and the routing table. Use it to answer questions like "what is listening on port 8080?", "which process owns this connection?", or "is something unexpected phoning home?". The PowerShell equivalent is Get-NetTCPConnection / Get-NetUDPEndpoint.
Availability
netstat ships as C:\Windows\System32\netstat.exe on every Windows version.
netstat /?
Output:
Displays protocol statistics and current TCP/IP network connections.
NETSTAT [-a] [-b] [-e] [-f] [-n] [-o] [-p proto] [-r] [-s] [-t] [-x] [-y] [interval]
Syntax
netstat [options] [interval]
Output: (connection list or statistics)
Essential options
| Switch | Meaning |
|---|---|
-a | All connections and listening ports (TCP and UDP) |
-n | Numeric addresses and ports — no DNS/service lookups |
-o | Add the owning process ID (PID) to each entry |
-b | Add the executable name (and component DLLs) — requires elevation |
-e | Ethernet statistics (bytes/packets sent and received) |
-r | Display the routing table |
-s | Per-protocol statistics (TCP, UDP, IP, ICMP) |
-p proto | Filter to a specific protocol: TCP, UDP, TCPv6, UDPv6 |
-f | Display FQDNs for foreign addresses |
interval | Refresh output every N seconds (Ctrl+C to stop) |
Active connections
Running netstat with no arguments lists only established TCP connections.
netstat
Output:
Active Connections
Proto Local Address Foreign Address State
TCP 192.168.1.100:49732 93.184.216.34:443 ESTABLISHED
TCP 192.168.1.100:49735 140.82.121.4:443 ESTABLISHED
TCP 192.168.1.100:49740 1.2.3.4:80 TIME_WAIT
All ports including listeners (-a)
-a includes every TCP listener (state LISTENING) and all UDP endpoints in addition to established connections — essential for auditing what services are open on a machine.
netstat -a
Output:
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING
TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING
TCP 192.168.1.100:49732 93.184.216.34:443 ESTABLISHED
UDP 0.0.0.0:53 *:*
UDP 0.0.0.0:67 *:*
Numeric output (-n)
-n skips DNS and service-name resolution, making output appear immediately and avoiding delays from failed reverse lookups.
netstat -an
Output:
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING
TCP 192.168.1.100:49732 93.184.216.34:443 ESTABLISHED
UDP 0.0.0.0:53 *:*
Show owning PID (-o)
-o adds a PID column, letting you cross-reference with tasklist to identify the process behind each connection.
netstat -ano
Output:
Active Connections
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING 4
TCP 192.168.1.100:49732 93.184.216.34:443 ESTABLISHED 8420
UDP 0.0.0.0:53 *:* 1048
Show executable name (-b)
-b adds the executable (and loaded DLLs) responsible for each socket. It requires elevation (run cmd.exe as Administrator).
netstat -ab
Output:
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
[httpd.exe]
TCP 192.168.1.100:49732 93.184.216.34:443 ESTABLISHED
[chrome.exe]
Interface statistics (-e)
-e shows Ethernet-level counts: bytes, unicast packets, non-unicast packets, discards, errors, and unknown protocols for each interface.
netstat -e
Output:
Interface Statistics
Received Sent
Bytes 1234567890 987654321
Unicast packets 12345678 9876543
Non-unicast packets 12345 9876
Discards 0 0
Errors 0 0
Unknown protocols 0
Routing table (-r)
-r prints the IP routing table — equivalent to route print. Shows destination networks, gateway, interface, and metric.
netstat -r
Output:
===========================================================================
Interface List
4...00 1a 2b 3c 4d 5e ......Intel(R) Ethernet Controller
1...........................Software Loopback Interface 1
===========================================================================
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.100 25
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
192.168.1.0 255.255.255.0 On-link 192.168.1.100 281
===========================================================================
Filtering by protocol (-p)
-p proto limits output to a single protocol. Valid values: TCP, UDP, TCPv6, UDPv6, IP, IPv6, ICMP, ICMPv6.
netstat -an -p TCP
Output:
Active Connections
Proto Local Address Foreign Address State
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING
TCP 192.168.1.100:49732 93.184.216.34:443 ESTABLISHED
Continuous refresh
Providing a number as the last argument refreshes output every N seconds until Ctrl+C is pressed.
netstat -ano 5
Output:
Active Connections
...
(refreshes every 5 seconds)
TCP connection states
netstat outputs a State column for TCP rows. Understanding the state machine is what separates "I see a connection" from "I understand what the connection is doing".
| State | Meaning |
|---|---|
LISTENING | Socket is bound and waiting for incoming connections |
SYN_SENT | Client sent SYN, waiting for server's SYN/ACK |
SYN_RECEIVED | Server received SYN, sent SYN/ACK, awaiting final ACK |
ESTABLISHED | Three-way handshake complete; data can flow |
FIN_WAIT_1 | Local side sent FIN, awaiting ACK |
FIN_WAIT_2 | Local side's FIN was ACK'd, awaiting remote FIN |
CLOSE_WAIT | Remote sent FIN; local app must close the socket |
CLOSING | Both sides sent FIN simultaneously |
LAST_ACK | Local FIN sent after remote FIN; awaiting final ACK |
TIME_WAIT | Connection closed; waiting 2×MSL (~4 min) before reuse |
DELETE_TCB | Cleanup phase; socket about to be freed |
A pile of TIME_WAIT entries is normal under load (each closed outbound connection sits in TIME_WAIT for ~4 minutes). A pile of CLOSE_WAIT entries is a bug — your application failed to call close() after the peer disconnected.
Count current connections by state:
netstat -an | Select-String -Pattern '^\s+TCP' |
ForEach-Object { ($_ -split '\s+')[-1] } |
Group-Object | Sort-Object Count -Descending
Output:
Count Name
----- ----
42 ESTABLISHED
18 TIME_WAIT
7 LISTENING
2 CLOSE_WAIT
Detailed per-protocol statistics (-s)
-s prints per-protocol counters since boot: segments sent/received, retransmits, resets, errors, listening sockets dropped. Combine with -p to focus on one protocol. Useful for diagnosing packet-loss symptoms (high retransmit count) or misconfigured firewalls (resets).
netstat -s -p TCP
Output:
TCP Statistics for IPv4
Active Opens = 5132
Passive Opens = 412
Failed Connection Attempts = 18
Reset Connections = 7
Current Connections = 48
Segments Received = 9821334
Segments Sent = 9712238
Segments Retransmitted = 17421
A retransmit ratio > 1 % suggests packet loss on the path. Reset Connections rising fast points to a firewall RST or a server force-closing connections.
Connection offload extension (-t, -x, -y)
These switches expose Windows-specific stack internals rarely needed except for performance triage.
| Switch | Meaning |
|---|---|
-t | Show TCP Chimney offload state per connection (NIC offloads handshake) |
-x | NetworkDirect connections, listeners, and shared endpoints (RDMA) |
-y | TCP template selected for each connection (Internet, Datacenter, Custom) |
netstat -ant
Output:
Proto Local Address Foreign Address State Offload State
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING InHost
TCP 192.168.1.100:49732 93.184.216.34:443 ESTABLISHED InHost
InHost means the OS TCP/IP stack handles the connection; Offloaded means the NIC is processing it directly.
PowerShell equivalents
Get-NetTCPConnection and Get-NetUDPEndpoint (Windows 8+/Server 2012+) are the structured replacements for netstat -an. They emit objects with typed properties — pipe them into Where-Object, Group-Object, or Export-Csv for analysis.
Get-NetTCPConnection -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess,
@{N='Process';E={(Get-Process -Id $_.OwningProcess).Name}}
Output:
LocalAddress LocalPort OwningProcess Process
------------ --------- ------------- -------
0.0.0.0 80 4 System
0.0.0.0 135 936 svchost
0.0.0.0 3389 1812 svchost
0.0.0.0 5985 4 System
0.0.0.0 8080 5432 node
Filter to established connections to a specific remote IP:
Get-NetTCPConnection -State Established |
Where-Object RemoteAddress -like '93.*' |
Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort,
@{N='Process';E={(Get-Process -Id $_.OwningProcess).Name}}
Output:
LocalAddress LocalPort RemoteAddress RemotePort Process
------------ --------- ------------- ---------- -------
192.168.1.100 49732 93.184.216.34 443 chrome
Find the owning process for a specific local port — the modern equivalent of netstat -ano | findstr :8080:
Get-Process -Id (Get-NetTCPConnection -LocalPort 8080).OwningProcess
Output:
Handles NPM(K) PM(K) WS(K) CPU(s) Id ProcessName
------- ------ ----- ----- ------ -- -----------
412 24 42312 58124 2.18 5432 node
UDP listeners (no state column — UDP is connectionless):
Get-NetUDPEndpoint |
Select-Object LocalAddress, LocalPort,
@{N='Process';E={(Get-Process -Id $_.OwningProcess).Name}}
Output:
LocalAddress LocalPort Process
------------ --------- -------
0.0.0.0 53 dns
0.0.0.0 67 svchost
0.0.0.0 123 w32time
0.0.0.0 5353 dns
Test-NetConnection — the diagnostic companion
Test-NetConnection is the PowerShell equivalent of "open a TCP socket to host:port and tell me if it succeeded". Cleaner than telnet (which Windows no longer ships by default) and richer than ping (which is ICMP-only).
Test-NetConnection -ComputerName myhost -Port 443
Output:
ComputerName : myhost
RemoteAddress : 192.168.1.50
RemotePort : 443
InterfaceAlias : Ethernet
SourceAddress : 192.168.1.100
TcpTestSucceeded : True
Full traceroute + reachability + DNS in one call:
Test-NetConnection -ComputerName myhost -TraceRoute -InformationLevel Detailed
Output:
ComputerName : myhost
RemoteAddress : 192.168.1.50
NameResolutionResults : 192.168.1.50
InterfaceAlias : Ethernet
SourceAddress : 192.168.1.100
PingSucceeded : True
PingReplyDetails (RTT) : 1 ms
TraceRoute : 192.168.1.1, 192.168.1.50
High-performance alternative — netstat -nao vs Get-NetTCPConnection
On a busy server with tens of thousands of connections, netstat -ano rebuilds the entire table on every invocation and can take several seconds. Get-NetTCPConnection reads directly from the kernel's TCP table via the iphlpapi.dll GetExtendedTcpTable API and is roughly 10x faster.
Measure-Command { netstat -ano | Out-Null }
Measure-Command { Get-NetTCPConnection | Out-Null }
Output:
TotalMilliseconds : 482
TotalMilliseconds : 47
For sustained monitoring (continuous refresh) use a PowerShell job rather than netstat -ano 5 — it produces objects you can stream into a CSV or a SIEM.
while ($true) {
Get-NetTCPConnection -State Established |
Select-Object @{N='Time';E={Get-Date -Format 'HH:mm:ss'}},
LocalPort, RemoteAddress, RemotePort, OwningProcess |
Export-Csv -Path C:\Logs\connections.csv -Append -NoTypeInformation
Start-Sleep 5
}
Output:
(none — appends rows to C:\Logs\connections.csv every 5 seconds)
Common pitfalls
-brequires elevation — running without Administrator rights produces "The requested operation requires elevation" per connection; run from an elevated prompt.-bis slow — it loads DLL metadata for every socket; prefer-o+tasklistwhen speed matters.-sand-eare aggregate — they show totals since last boot, not a rate; usenetstat -e N(with interval) and subtract consecutive readings for throughput.- UDP entries show no state — UDP is connectionless;
netstat -alists UDP endpoints but the State column is always blank. - PID 4 is the System process — port 80/443 owned by PID 4 means the Windows HTTP Server API (http.sys) is in use, not a user-space web server; look for IIS, WinRM, or other http.sys consumers.
netstatis being deprecated — Microsoft's recommended path isGet-NetTCPConnection/Get-NetUDPEndpoint.netstat.execontinues to ship for backwards compatibility but new switches stopped being added after Server 2012.- No JSON output — unlike
ip -jorss -J,netstatonly emits human-readable text. For machine-readable output useGet-NetTCPConnection | ConvertTo-Json. - CLOSE_WAIT pileup means your bug — if you see many
CLOSE_WAITentries with the same PID, that process is leaking sockets (forgot to callclose()/Dispose()). -rshows IPv4 only — to see the full routing table including IPv6, useroute print(which includes both) orGet-NetRoute.-f(FQDN lookup) hangs on bad DNS — if reverse DNS is broken,netstat -fblocks per-row; always combine with-nfor fast output and look up names explicitly withResolve-DnsNamewhen needed.
Real-world recipes
Find what process is listening on a specific port
netstat -ano | findstr ":8080"
Output:
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 5432
Then look up PID 5432:
tasklist /fi "PID eq 5432"
Output:
Image Name PID Session Name Session# Mem Usage
========================= ======== ================ =========== ============
node.exe 5432 Console 1 42,312 K
List all established connections with process names
netstat -ano | findstr ESTABLISHED
Output:
TCP 192.168.1.100:49732 93.184.216.34:443 ESTABLISHED 8420
TCP 192.168.1.100:49740 140.82.121.4:443 ESTABLISHED 8420
Audit all open ports for a security review
netstat -an -p TCP | findstr LISTENING > C:\Audit\open_ports.txt
type C:\Audit\open_ports.txt
Output:
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
TCP 0.0.0.0:443 0.0.0.0:0 LISTENING
TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING
Monitor connection count every 10 seconds
netstat -ano 10 | findstr ESTABLISHED
Output:
(connection list refreshes every 10 seconds)
Find which process is hammering a remote endpoint
When a server has many outbound connections to one remote IP, group by PID to find the culprit.
Get-NetTCPConnection -State Established |
Where-Object RemoteAddress -eq '10.0.0.50' |
Group-Object OwningProcess |
ForEach-Object {
[PSCustomObject]@{
PID = $_.Name
Process = (Get-Process -Id $_.Name -ErrorAction SilentlyContinue).Name
Connections = $_.Count
}
} | Sort-Object Connections -Descending
Output:
PID Process Connections
--- ------- -----------
5432 node 148
1812 svchost 12
8420 chrome 3
Detect a CLOSE_WAIT leak in a long-running service
A growing CLOSE_WAIT count is the unmistakable signature of a socket leak. Sample over time and alert when the count crosses a threshold.
$pid = (Get-Process myservice).Id
while ($true) {
$count = (Get-NetTCPConnection -State CloseWait -OwningProcess $pid -ErrorAction SilentlyContinue).Count
"{0:HH:mm:ss} CLOSE_WAIT for PID $pid : $count" -f (Get-Date)
if ($count -gt 50) {
Write-Warning "Socket leak suspected in PID $pid"
}
Start-Sleep 10
}
Output:
14:00:00 CLOSE_WAIT for PID 5432 : 2
14:00:10 CLOSE_WAIT for PID 5432 : 4
14:00:20 CLOSE_WAIT for PID 5432 : 8
14:00:30 CLOSE_WAIT for PID 5432 : 15
14:00:40 CLOSE_WAIT for PID 5432 : 32
14:00:50 CLOSE_WAIT for PID 5432 : 58
WARNING: Socket leak suspected in PID 5432
Map every listening socket to its service
Get-Service can be joined to Get-NetTCPConnection via PID to build a "what service answers on what port?" inventory.
Get-NetTCPConnection -State Listen |
ForEach-Object {
$svc = Get-CimInstance Win32_Service -Filter "ProcessId = $($_.OwningProcess)"
[PSCustomObject]@{
Port = $_.LocalPort
PID = $_.OwningProcess
Process = (Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).Name
Service = $svc.Name
}
} | Sort-Object Port
Output:
Port PID Process Service
---- --- ------- -------
80 4 System HTTP
135 936 svchost RpcSs
445 4 System LanmanServer
3389 1812 svchost TermService
5985 4 System WinRM
8080 5432 node
Export a snapshot to JSON for ingestion by a SIEM
Get-NetTCPConnection |
Select-Object CreationTime, LocalAddress, LocalPort, RemoteAddress, RemotePort, State,
OwningProcess,
@{N='Process';E={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).Name}} |
ConvertTo-Json -Depth 3 |
Out-File C:\Audit\connections.json -Encoding utf8
Output:
(none — JSON written to C:\Audit\connections.json)
Related references
| Tool | Purpose |
|---|---|
Get-NetTCPConnection | Modern PowerShell replacement (recommended) |
Get-NetUDPEndpoint | UDP listener inventory |
Test-NetConnection | TCP reach test (replaces telnet) |
Resolve-DnsName | DNS lookup (replaces nslookup for scripts) |
tasklist /fi "PID eq <n>" | Process lookup by PID |
Get-Process -Id <n> | PowerShell equivalent |
Get-NetRoute | Routing table |
route print | Routing table (CMD) |
netsh advfirewall firewall show rule | Firewall rules for blocked ports |
Sysinternals tcpview | GUI live view of TCP/UDP state |