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.

cmd
netstat /?

Output:

css
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

cmd
netstat [options] [interval]

Output: (connection list or statistics)

Essential options

SwitchMeaning
-aAll connections and listening ports (TCP and UDP)
-nNumeric addresses and ports — no DNS/service lookups
-oAdd the owning process ID (PID) to each entry
-bAdd the executable name (and component DLLs) — requires elevation
-eEthernet statistics (bytes/packets sent and received)
-rDisplay the routing table
-sPer-protocol statistics (TCP, UDP, IP, ICMP)
-p protoFilter to a specific protocol: TCP, UDP, TCPv6, UDPv6
-fDisplay FQDNs for foreign addresses
intervalRefresh output every N seconds (Ctrl+C to stop)

Active connections

Running netstat with no arguments lists only established TCP connections.

cmd
netstat

Output:

css
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.

cmd
netstat -a

Output:

css
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.

cmd
netstat -an

Output:

css
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.

cmd
netstat -ano

Output:

css
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).

cmd
netstat -ab

Output:

less
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.

cmd
netstat -e

Output:

graphql
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.

cmd
netstat -r

Output:

markdown
===========================================================================
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.

cmd
netstat -an -p TCP

Output:

css
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.

cmd
netstat -ano 5

Output:

python-repl
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".

StateMeaning
LISTENINGSocket is bound and waiting for incoming connections
SYN_SENTClient sent SYN, waiting for server's SYN/ACK
SYN_RECEIVEDServer received SYN, sent SYN/ACK, awaiting final ACK
ESTABLISHEDThree-way handshake complete; data can flow
FIN_WAIT_1Local side sent FIN, awaiting ACK
FIN_WAIT_2Local side's FIN was ACK'd, awaiting remote FIN
CLOSE_WAITRemote sent FIN; local app must close the socket
CLOSINGBoth sides sent FIN simultaneously
LAST_ACKLocal FIN sent after remote FIN; awaiting final ACK
TIME_WAITConnection closed; waiting 2×MSL (~4 min) before reuse
DELETE_TCBCleanup 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:

powershell
netstat -an | Select-String -Pattern '^\s+TCP' |
    ForEach-Object { ($_ -split '\s+')[-1] } |
    Group-Object | Sort-Object Count -Descending

Output:

diff
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).

cmd
netstat -s -p TCP

Output:

ini
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.

SwitchMeaning
-tShow TCP Chimney offload state per connection (NIC offloads handshake)
-xNetworkDirect connections, listeners, and shared endpoints (RDMA)
-yTCP template selected for each connection (Internet, Datacenter, Custom)
cmd
netstat -ant

Output:

css
  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.

powershell
Get-NetTCPConnection -State Listen |
    Select-Object LocalAddress, LocalPort, OwningProcess,
                  @{N='Process';E={(Get-Process -Id $_.OwningProcess).Name}}

Output:

yaml
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:

powershell
Get-NetTCPConnection -State Established |
    Where-Object RemoteAddress -like '93.*' |
    Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort,
                  @{N='Process';E={(Get-Process -Id $_.OwningProcess).Name}}

Output:

arduino
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:

powershell
Get-Process -Id (Get-NetTCPConnection -LocalPort 8080).OwningProcess

Output:

scss
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):

powershell
Get-NetUDPEndpoint |
    Select-Object LocalAddress, LocalPort,
                  @{N='Process';E={(Get-Process -Id $_.OwningProcess).Name}}

Output:

arduino
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).

powershell
Test-NetConnection -ComputerName myhost -Port 443

Output:

yaml
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:

powershell
Test-NetConnection -ComputerName myhost -TraceRoute -InformationLevel Detailed

Output:

yaml
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.

powershell
Measure-Command { netstat -ano | Out-Null }
Measure-Command { Get-NetTCPConnection | Out-Null }

Output:

yaml
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.

powershell
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:

sql
(none — appends rows to C:\Logs\connections.csv every 5 seconds)

Common pitfalls

  1. -b requires elevation — running without Administrator rights produces "The requested operation requires elevation" per connection; run from an elevated prompt.
  2. -b is slow — it loads DLL metadata for every socket; prefer -o + tasklist when speed matters.
  3. -s and -e are aggregate — they show totals since last boot, not a rate; use netstat -e N (with interval) and subtract consecutive readings for throughput.
  4. UDP entries show no state — UDP is connectionless; netstat -a lists UDP endpoints but the State column is always blank.
  5. 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.
  6. netstat is being deprecated — Microsoft's recommended path is Get-NetTCPConnection / Get-NetUDPEndpoint. netstat.exe continues to ship for backwards compatibility but new switches stopped being added after Server 2012.
  7. No JSON output — unlike ip -j or ss -J, netstat only emits human-readable text. For machine-readable output use Get-NetTCPConnection | ConvertTo-Json.
  8. CLOSE_WAIT pileup means your bug — if you see many CLOSE_WAIT entries with the same PID, that process is leaking sockets (forgot to call close()/Dispose()).
  9. -r shows IPv4 only — to see the full routing table including IPv6, use route print (which includes both) or Get-NetRoute.
  10. -f (FQDN lookup) hangs on bad DNS — if reverse DNS is broken, netstat -f blocks per-row; always combine with -n for fast output and look up names explicitly with Resolve-DnsName when needed.

Real-world recipes

Find what process is listening on a specific port

cmd
netstat -ano | findstr ":8080"

Output:

yaml
  TCP    0.0.0.0:8080           0.0.0.0:0              LISTENING       5432

Then look up PID 5432:

cmd
tasklist /fi "PID eq 5432"

Output:

arduino
Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
node.exe                      5432 Console                    1     42,312 K

List all established connections with process names

cmd
netstat -ano | findstr ESTABLISHED

Output:

yaml
  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

cmd
netstat -an -p TCP | findstr LISTENING > C:\Audit\open_ports.txt
type C:\Audit\open_ports.txt

Output:

code
  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

cmd
netstat -ano 10 | findstr ESTABLISHED

Output:

scss
(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.

powershell
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:

yaml
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.

powershell
$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:

yaml
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.

powershell
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:

yaml
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

powershell
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:

css
(none — JSON written to C:\Audit\connections.json)
ToolPurpose
Get-NetTCPConnectionModern PowerShell replacement (recommended)
Get-NetUDPEndpointUDP listener inventory
Test-NetConnectionTCP reach test (replaces telnet)
Resolve-DnsNameDNS lookup (replaces nslookup for scripts)
tasklist /fi "PID eq <n>"Process lookup by PID
Get-Process -Id <n>PowerShell equivalent
Get-NetRouteRouting table
route printRouting table (CMD)
netsh advfirewall firewall show ruleFirewall rules for blocked ports
Sysinternals tcpviewGUI live view of TCP/UDP state

Sources