How to Audit Active TCP Connections and Socket States in Windows 11 Using PowerShell

In enterprise network security, systems administration, and malware incident response, auditing active TCP network sockets is essential for identifying unauthorized outbound connections, listening backdoors, and hung network services. Traditionally, administrators relied on legacy command-line utilities such as netstat -ano to audit network traffic. However, netstat outputs unstructured text that cannot be filtered or manipulated programmatically in modern automation pipelines.

Windows 11 includes the Get-NetTCPConnection PowerShell cmdlet within the core NetTCPIP module. This tool queries the kernel TCP/IP stack directly, returning structured objects detailing local and remote IP addresses, port numbers, owning Process IDs (PIDs), and standard TCP state machine flags. System administrators and security engineers can audit established sessions, track TIME_WAIT socket exhaustion, and correlate network traffic with running processes. This guide demonstrates how to audit active TCP connections and socket states in Windows 11 using PowerShell.

Querying Active TCP Connections

The Get-NetTCPConnection cmdlet returns active TCP sockets across all physical, virtual, and loopback network interfaces.

Listing All Open Sockets

  1. Right-click the Start button on Windows 11 and choose Terminal (Admin) or PowerShell (Admin).
  2. Execute the basic query:
Get-NetTCPConnection

Windows outputs a table displaying core network socket properties:

LocalAddress    LocalPort RemoteAddress   RemotePort State       OwningProcess
------------    --------- -------------   ---------- -----       -------------
0.0.0.0         445       0.0.0.0         0          Listen      4
192.168.1.50    51280     142.250.180.206 443        Established 8920
127.0.0.1       5040      0.0.0.0         0          Listen      1124
192.168.1.50    51284     20.42.65.112    443        TimeWait    0

Filtering by TCP State Machine Status

The TCP protocol transitions through well-defined operating states during a connection’s lifecycle. Filter connections by passing specific states to the -State parameter:

1. Auditing Listening Ports (Inbound Attack Surface)

To inspect services currently listening for incoming connections:

Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess | Sort-Object LocalPort

This command reveals all open ports, allowing you to audit exposed network services and verify that unwanted daemons are not listening on external interfaces.

2. Auditing Established Outbound Sessions

To view active, established sessions currently exchanging data:

Get-NetTCPConnection -State Established | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess

3. Checking Socket Exhaustion with TIME_WAIT and CLOSE_WAIT

High-load web servers or misconfigured API clients often leave thousands of sockets in TimeWait or CloseWait states, exhausting ephemeral port ranges. Count sockets grouped by state:

Get-NetTCPConnection | Group-Object State | Select-Object Count, Name

If TimeWait counts number in the tens of thousands, investigate connection pooling configurations and TCP TIME_WAIT delay timers.

Correlating Sockets with Process Names and Executable Paths

Knowing that an unknown connection is established from port 51280 to an external IP address is unhelpful without knowing which software executable is responsible. Correlate the OwningProcess PID with Get-Process to display friendly application names and executable file paths:

Get-NetTCPConnection -State Established | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess, @{Name="ProcessName"; Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}}, @{Name="Path"; Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).Path}} | Format-Table -AutoSize

This pipeline outputs the exact process name (e.g. chrome, teams, or powershell) and the full disk path (e.g. C:\Program Files\...) for every active connection.

Filtering by Remote IP Address and Subnet

During security investigations or network troubleshooting, isolate connections communicating with a specific remote IP address or cloud provider subnet:

Get-NetTCPConnection -RemoteAddress "142.250.180.206"

To filter for all outbound connections communicating outside the private local network (excluding private RFC 1918 subnets like 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16):

Get-NetTCPConnection -State Established | Where-Object { $_.RemoteAddress -notlike "192.168.*" -and $_.RemoteAddress -notlike "10.*" -and $_.RemoteAddress -notlike "127.*" } | Select-Object LocalPort, RemoteAddress, RemotePort, OwningProcess

Monitoring Live Connection Changes Dynamically

To create a lightweight real-time network activity monitor that sweeps for newly established connections every 2 seconds:

while ($true) {
    Clear-Host
    Write-Host "Active Established TCP Connections at $(Get-Date -Format 'HH:mm:ss'):" -ForegroundColor Cyan
    Get-NetTCPConnection -State Established | Select-Object -First 15 LocalPort, RemoteAddress, RemotePort, @{Name="Process"; Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} | Format-Table -AutoSize
    Start-Sleep -Seconds 2
}

Press Ctrl+C to exit the live monitoring loop.

Administrative Safeguards

  • Elevated Administrator Privileges: While non-elevated users can query their own user-session sockets, inspecting system-level processes (such as PID 4 System or SVCHOST service hosts) requires an elevated PowerShell console.
  • Security Auditing: The Get-NetTCPConnection cmdlet is completely read-only and safe to execute in production environments without disrupting active data transfers.
  • IPv4 vs IPv6: The cmdlet automatically monitors both IPv4 and IPv6 address families without requiring separate flags.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.