Skip to content

PowerShell Network Statistics

Use PowerShell cmdlets like Get-NetTCPConnection, Get-NetAdapterStatistics, and Get-NetIPStatistics to monitor live network activity, TCP connections, adapter traffic, and IP protocol errors. Modern alternatives to netstat with structured object output.

Beyond configuration and connectivity, PowerShell can also inspect live network activity. This includes active TCP connections, adapter-level traffic counters, and protocol statistics. It offers object-based alternatives to tools such as netstat. Network telemetry and socket diagnostics in PowerShell are driven by the NetTCPIP and NetAdapter modules. Cmdlets such as Get-NetTCPConnection, Get-NetAdapterStatistics, and Get-NetIPStatistics replace legacy utilities like netstat.exe and interface hardware monitors, outputting structured objects that report active TCP sockets, hardware frame counters, packet drop rates, and IP-layer protocol errors.

Viewing Active Connections with Get-NetTCPConnection

The Get-NetTCPConnection cmdlet inspects the active TCP transport layer, acting as the structured object equivalent to netstat -ano. It catalogs local and remote IP addresses, ports, connection states, and the process identifier (PID) that owns each socket.

Consolepowershell
Get-NetTCPConnection
Outputplaintext
LocalAddress   LocalPort  RemoteAddress   RemotePort  State        AppliedSetting
------------   ---------  -------------   ----------  -----        --------------
0.0.0.0        135        0.0.0.0         0           Listen
192.168.1.42   51022      142.250.72.14   443         Established
127.0.0.1      5040       127.0.0.1       5041        Established

where State is the connection status: Listen, Established, TimeWait, CloseWait, etc.

Filtering by Port or State

Consolepowershell
Get-NetTCPConnection -LocalPort 443
Get-NetTCPConnection -State Established

where:

  • -LocalPort filters connections bound to a specific local port.
  • -State filters connections by their current TCP state.

Correlating Connections to Processes

Each connection includes an OwningProcess property (PID), which can be joined with Get-Process to identify which application owns the connection.

get-tcp-connections.ps1powershell
Get-NetTCPConnection -State Listen | 
    Select-Object -Property LocalAddress, LocalPort, OwningProcess,
        @{Name="ProcessName"; Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
    Sort-Object -Property LocalPort

where:

  • Get-NetTCPConnection retrieves the state of active TCP connections and listening sockets.
  • -State filters connections by TCP lifecycle states (such as Listen, Established, TimeWait, CloseWait, or SynSent).
  • LocalAddress is the IP address assigned to the local interface hosting the socket.
  • LocalPort is the TCP port number bound by the application.
  • OwningProcess is the PID of the process managing the socket.
  • (Get-Process -Id ...) is a calculated property expression dynamically looking up the process executable name corresponding to the PID.
Consolepowershell
./get-tcp-connections.ps1
Outputplaintext
LocalAddress LocalPort OwningProcess ProcessName
------------ --------- ------------- -----------
0.0.0.0             80          4112 httpd
0.0.0.0            135          1024 svchost
0.0.0.0            445             4 System
0.0.0.0           3389          1288 TermService
0.0.0.0           5985          2340 wsmprovhost

Viewing Adapter Traffic with Get-NetAdapterStatistics

The Get-NetAdapterStatistics cmdlet queries Layer 2 packet counters, byte throughput, and hardware frame errors for physical and virtual network adapters.

get-adapter-stats.ps1powershell
Get-NetAdapterStatistics | 
    Select-Object -Property Name,
        @{Name="Received(MB)"; Expression={[math]::Round($_.ReceivedBytes / 1MB, 2)}},
        @{Name="Sent(MB)"; Expression={[math]::Round($_.SentBytes / 1MB, 2)}},
        ReceivedDiscardedPackets,
        OutboundDiscardedPackets

where:

  • Get-NetAdapterStatistics queries low-level device counters from the network interface driver.
  • ReceivedBytes / SentBytes are total cumulative data transferred through the adapter since system boot or driver re-initialization.
  • ReceivedDiscardedPackets are packets dropped by the adapter due to buffer starvation, hardware saturation, or driver exhaustion.
  • OutboundDiscardedPackets are packets dropped before transmission.
Consolepowershell
./get-adapter-stats.ps1
Outputplaintext
Name                     : Ethernet0
Received(MB)             : 0.61
Sent(MB)                 : 0.09
ReceivedDiscardedPackets : 0
OutboundDiscardedPackets : 0

Measuring Throughput Over Time

measure-throughput.ps1powershell
$before = Get-NetAdapterStatistics -Name "Ethernet"
Start-Sleep -Seconds 5
$after = Get-NetAdapterStatistics -Name "Ethernet"

$receivedMBps = (($after.ReceivedBytes - $before.ReceivedBytes) / 5) / 1MB
$sentMBps = (($after.SentBytes - $before.SentBytes) / 5) / 1MB

Write-Output "Received: $([math]::Round($receivedMBps,2)) MB/s"
Write-Output "Sent: $([math]::Round($sentMBps,2)) MB/s"

where: $before / $after: snapshots of the counters taken 5 seconds apart.

  • Dividing the byte delta by elapsed seconds and 1MB converts the result into megabytes per second.
Consolepowershell
./measure-throughput.ps1
Outputplaintext
Received: 1.24 MB/s
Sent: 0.31 MB/s

Viewing Protocol Statistics with Get-NetIPStatistics

The Get-NetIPStatistics cmdlet provides Layer 3 telemetry, querying the operational state of IPv4 and IPv6 stacks. It tracks packet forwarding, routing failures, fragmentation statistics, and header reassembly errors, much like the output of netstat -s.

get-ip-statistics.ps1powershell
Get-NetIPStatistics -AddressFamily IPv4 | 
    Select-Object -Property DatagramsReceived, 
        ForwardedDatagrams, 
        ReceivedAddressErrors, 
        ReceivedPacketsDiscarded, 
        ReassemblyFailures

where:

  • Get-NetIPStatistics queries core network layer metrics across the host's IP implementation.
  • -AddressFamily IPv4 restricts statistics to IPv4 metrics (IPv6 can also be targeted).
  • ForwardedDatagrams is the number of packets routed by the host when acting as an IP router/gateway.
  • ReceivedAddressErrors are packets received where the target IP was invalid or not hosted locally.
  • ReceivedPacketsDiscarded are packets discarded due to memory constraints or IP protocol-level invalidations.
  • ReassemblyFailures are fragmented packets that timed out before total reassembly.
Consolepowershell
./get-ip-statistics.ps1
Outputplaintext
DatagramsReceived        : 1245892
ForwardedDatagrams       : 0
ReceivedAddressErrors    : 4
ReceivedPacketsDiscarded : 0
ReassemblyFailures       : 0

Comparing IPv4 vs IPv6 Statistics

Consolepowershell
Get-NetIPStatistics -AddressFamily IPv6

where -AddressFamily filters results to IPv4 or IPv6 statistics specifically.

Practical Usage

Connection and Traffic Health Check

A common diagnostic script combines connection counts, traffic volume, and discarded packet counters into a single health snapshot.

network-health-check.ps1powershell
param([string]$AdapterName = "Ethernet")

$connections = Get-NetTCPConnection -State Established
$stats       = Get-NetAdapterStatistics -Name $AdapterName
$ipStats     = Get-NetIPStatistics -AddressFamily IPv4

[PSCustomObject]@{
    ActiveConnections   = $connections.Count
    ReceivedMB          = [math]::Round($stats.ReceivedBytes / 1MB, 2)
    SentMB              = [math]::Round($stats.SentBytes / 1MB, 2)
    PacketsDiscarded    = $ipStats.PacketsDiscarded
}

where:

  • $connections.Count is the total number of currently established TCP connections.
  • [math]::Round(... / 1MB, 2) converts cumulative byte counters into readable megabyte values.
Consolepowershell
./network-health-check.ps1 -AdapterName "Ethernet"
Outputplaintext
ActiveConnections ReceivedMB SentMB PacketsDiscarded
----------------- ---------- ------ ----------------
42                1510.32    431.02 12

Investigating Suspicious External Connections

Security auditing workflows frequently require scanning actively connected outbound sockets, flagging connections established to non-private IP addresses, and correlating them with the running binary on the local machine.

audit-external-connections.ps1powershell
$connections = Get-NetTCPConnection -State Established | 
    Where-Object { 
        $_.RemoteAddress -notmatch "^127\." -and
        $_.RemoteAddress -notmatch "^10\." -and
        $_.RemoteAddress -notmatch "^172\.(1[6-9]|2[0-9]|3[0-1])\." -and
        $_.RemoteAddress -notmatch "^192\.168\." -and
        $_.RemoteAddress -notmatch "^::1$" -and
        $_.RemoteAddress -notmatch "^fe80:"
    }

$auditReport = foreach ($conn in $connections) {
    $proc = Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue
    
    [PSCustomObject]@{
        LocalPort     = $conn.LocalPort
        RemoteAddress = $conn.RemoteAddress
        RemotePort    = $conn.RemotePort
        PID           = $conn.OwningProcess
        ProcessName   = if ($proc) { $proc.ProcessName } else { "Unknown / Terminated" }
        Executable    = if ($proc) { $proc.Path } else { "N/A" }
    }
}

$auditReport | Format-Table -AutoSize

where:

  • Get-NetTCPConnection -State Established restricts the scope strictly to active, streaming data sessions.
  • -notmatch uses regular expression patterns to exclude loopback, RFC1918 private IPv4 networks, and IPv6 link-local subnets.
  • $proc.Path identifies the exact on-disk binary executing the network connection, allowing verification against security policies.
Consolepowershell
./audit-external-connections.ps1
Outputplaintext
LocalPort RemoteAddress  RemotePort   PID ProcessName Executable
--------- -------------  ----------   --- ----------- ----------
    51234 140.82.112.4          443  6212 git         C:\Program Files\Git\cmd\git.exe
    51388 52.178.17.2           443  9820 pwsh        C:\Program Files\PowerShell\7\pwsh.exe
    51402 20.189.173.12         443  1104 msedge      C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
Navigation