courses

Windows Packet Capture

Capturing on Windows: native first, Wireshark second

This page covers packet capture on Windows across two categories:

For capture architecture and strategy (where to place a capture, how to get traffic to your sensor, physical taps, SPAN ports), see Network Traffic Capture. For analysis once you have a capture file, see tcpdump and tshark.

netsh trace

netsh trace is the older of the two tools, available since Windows 7. It uses Event Tracing for Windows (ETW) to capture network traffic and writes an .etl (Event Trace Log) file. The .etl format is Windows-native; converting to .pcapng requires an additional step.

Basic Usage

All netsh trace commands run in an elevated (Administrator) command prompt or PowerShell session.

Start a capture:

netsh trace start capture=yes tracefile=C:\capture\trace.etl

Stop the capture:

netsh trace stop

The stop command converts the .etl to a .cab file containing the trace and associated metadata.

Start with a capture filter (reduce noise):

netsh trace start capture=yes tracefile=C:\capture\trace.etl IPv4.Address=10.0.0.5

Capture on a specific interface:

# First, find interface names
netsh interface show interface

# Then specify it
netsh trace start capture=yes tracefile=C:\capture\trace.etl CaptureInterface="Ethernet"

Limit file size and duration:

netsh trace start capture=yes tracefile=C:\capture\trace.etl maxsize=500 filemode=circular

maxsize is in MB. filemode=circular overwrites the oldest data when full (useful for long-running captures); the default is linear (stops when full).

Capture Filters

netsh trace supports filters at capture time, which reduces the volume of data written to disk.

Filter Example Notes
IPv4.Address IPv4.Address=10.0.0.5 Matches src or dst
IPv4.SourceAddress IPv4.SourceAddress=10.0.0.5 Source only
IPv4.DestinationAddress IPv4.DestinationAddress=8.8.8.8 Destination only
IPv6.Address IPv6.Address=fe80::1 IPv6 equivalent
TCP.SourcePort TCP.SourcePort=443 TCP source port
TCP.DestinationPort TCP.DestinationPort=80 TCP destination port
Protocol Protocol=TCP TCP, UDP, ICMP
Ethernet.Type Ethernet.Type=0x0800 Ethertype filter

Multiple filters combine with AND logic:

netsh trace start capture=yes tracefile=C:\capture\trace.etl IPv4.Address=10.0.0.5 TCP.DestinationPort=443

Converting ETL to pcapng

The .etl file is not directly readable by Wireshark. Convert it using etl2pcapng, an open-source tool from Microsoft:

# Download etl2pcapng from https://github.com/microsoft/etl2pcapng/releases
etl2pcapng.exe C:\capture\trace.etl C:\capture\trace.pcapng

After conversion, open trace.pcapng in Wireshark or analyze with tshark.

Alternatively, Microsoft Network Monitor (deprecated but still available) and Microsoft Message Analyzer (also deprecated) can open .etl files natively. For new work, etl2pcapng + Wireshark is the supported path.

Checking Capture Status

netsh trace show status

Shows whether a capture is currently running, the output file path, and elapsed time.

pktmon

pktmon (Packet Monitor) was introduced in Windows 10 version 2004 (May 2020 Update) and Windows Server 2019. It offers more flexibility than netsh trace – multiple simultaneous capture points, component-level filtering, and native .pcapng output since Windows 11 / Server 2022. On older versions it outputs .etl only.

pktmon operates at multiple points in the Windows network stack simultaneously, which makes it particularly useful for diagnosing where in the stack packets are being dropped.

Basic Usage

All pktmon commands require an elevated prompt.

Start a capture (all interfaces, all traffic):

pktmon start --capture --file-name C:\capture\pktmon.etl

Stop the capture:

pktmon stop

Start with live display (no file):

pktmon start --capture --log-mode real-time

Limit to a specific interface:

# List interfaces with their component IDs
pktmon list

# Capture on a specific component ID
pktmon start --capture --comp 9 --file-name C:\capture\pktmon.etl

Filters

pktmon filters are added before starting a capture and persist until explicitly removed.

# Add a filter for a specific IP address
pktmon filter add -i 10.0.0.5

# Add a filter for a specific port
pktmon filter add -p 443

# Add a filter for a protocol
pktmon filter add --transport tcp

# Combine: specific host AND port
pktmon filter add -i 10.0.0.5 -p 443

# View active filters
pktmon filter list

# Remove all filters
pktmon filter remove

Filters combine with OR logic: a packet matching any filter is captured. Without any filters, all traffic is captured.

Converting pktmon Output

pktmon always writes .etl format. Convert to pcapng using the built-in etl2pcap subcommand — no external tool required:

pktmon etl2pcap C:\capture\pktmon.etl --out C:\capture\pktmon.pcapng

Useful etl2pcap flags:

Flag Effect
-o, --out <name> Output pcapng file name
-d, --drop-only Include only dropped packets
-c, --component-id <id> Filter to a specific stack component

Note that pcapng format loses drop-reason annotations present in the .etl; use pktmon etl2txt to preserve that detail for forensic analysis.

--pkt-size 0 on pktmon start captures full packet content (default truncates at 128 bytes):

pktmon start --capture --pkt-size 0 --file-name C:\capture\pktmon.etl

Packet Drop Analysis

One of pktmon’s distinctive features is identifying where in the network stack packets are being dropped.

# Show drop counters per network component
pktmon counters

# Reset counters
pktmon reset

# Show detailed drop log after capture
pktmon format C:\capture\pktmon.etl -o C:\capture\pktmon.txt

The formatted output shows each packet’s path through the Windows networking stack (NIC driver → NDIS filter drivers → WFP (Windows Filtering Platform) → TCP/IP stack → socket), identifying the exact component that dropped the packet and the reason code. This is far more useful for diagnosing Windows firewall and driver issues than netsh trace.

Multi-Component Capture

pktmon can capture at multiple stack layers simultaneously, labeling each packet with where it was seen:

# Capture at all stack components
pktmon start --capture --comp all --file C:\capture\pktmon.etl

This produces a trace showing the same packet at multiple points in the stack, allowing you to confirm it was received by the NIC driver but dropped by the WFP before reaching the socket layer, for example.

PowerShell: NetEventSession

The NetEventSession cmdlets provide a PowerShell wrapper around the same ETW infrastructure used by netsh trace, with finer-grained control over providers and filters.

# The target directory must exist before creating the session
New-Item -ItemType Directory -Force -Path C:\capture

# Create a new capture session
New-NetEventSession -Name "MyCapture" -LocalFilePath "C:\capture\trace.etl" -MaxFileSize 500

# Add a packet capture provider with an optional IP address filter
# IP filtering is a parameter of Add-NetEventPacketCaptureProvider, not a separate cmdlet
Add-NetEventPacketCaptureProvider -SessionName "MyCapture" -IpAddresses "10.0.0.5"

# Start the session
Start-NetEventSession -Name "MyCapture"

# ... wait ...

# Stop and clean up
Stop-NetEventSession -Name "MyCapture"
Remove-NetEventSession -Name "MyCapture"

The output .etl file is converted to pcapng with etl2pcapng, same as netsh trace.

PowerShell sessions are useful for remote capture via Invoke-Command on a remote host:

$session = New-PSSession -ComputerName remote-host
Invoke-Command -Session $session -ScriptBlock {
    New-Item -ItemType Directory -Force -Path C:\capture
    New-NetEventSession -Name "RemoteCapture" -LocalFilePath "C:\capture\trace.etl"
    Add-NetEventPacketCaptureProvider -SessionName "RemoteCapture"
    Start-NetEventSession -Name "RemoteCapture"
}

# ... wait for traffic of interest ...

Invoke-Command -Session $session -ScriptBlock {
    Stop-NetEventSession -Name "RemoteCapture"
    Remove-NetEventSession -Name "RemoteCapture"
}

# Copy the file back
Copy-Item -Path "\\remote-host\C$\capture\trace.etl" -Destination "C:\local\trace.etl"

This is a legitimate remote capture technique for Windows hosts where installing Wireshark is not an option.

Wireshark, tshark, and dumpcap

These tools require installation but are easier to use than the native tools, produce pcapng directly, and support a broader range of interface types. They all depend on Npcap as the underlying capture driver.

Npcap

Npcap is the maintained successor to the long-discontinued WinPcap. It provides the kernel-mode driver that Wireshark, tshark, dumpcap, and other tools use to capture packets on Windows.

The Wireshark installer bundles Npcap; if Wireshark is already installed, Npcap is already present. To verify:

Get-Service npcap

To install Npcap standalone, or to get a newer version than the one bundled with an older Wireshark install, download from npcap.com.

Key capabilities over WinPcap:

Feature Notes
Loopback capture Adds a “Npcap Loopback Adapter” interface; captures traffic between local processes
Raw 802.11 capture Monitor mode with radiotap headers, if the Wi-Fi driver supports it
Current Windows support Windows 7 through 11, x86/x64/ARM
Admin-only mode Optional; restricts capture to Administrator accounts

Wireshark

Wireshark is the standard GUI for packet capture and analysis. Install via winget (recommended — keeps it updated):

winget install --id WiresharkFoundation.Wireshark

Or download from wireshark.org. The installer bundles Npcap if it is not already present.

Starting a capture:

  1. Launch Wireshark as Administrator (required for capture)
  2. Select an interface from the welcome screen — sparklines show live traffic volume on each
  3. Optionally type a capture filter (BPF syntax) before starting
  4. Press Ctrl+E or click the blue shark fin to start; press Ctrl+E again to stop

Capture filter vs. display filter:

  Capture filter Display filter
Syntax BPF (tcp port 443) Wireshark (tls.handshake.type == 1)
Applied Before capture; drops non-matching packets from the file After capture; hides packets in view but keeps them in the file
Use when Disk space is a constraint and you know what you need Exploring an existing capture

Capturing loopback traffic:

Select “Npcap Loopback Adapter” in the interface list. This captures traffic between processes on the same machine — useful for testing local services or intercepting traffic from tools that do not go through a network adapter.

Key capture options (Capture → Options):

Option Notes
Promiscuous mode Default on; captures traffic not addressed to this host
Monitor mode Raw 802.11 frames; adapter and driver must support it
Snapshot length Bytes per packet; 0 = full packet
Ring buffer Rotate output files by size or time; set file count to limit disk use

tshark

tshark is Wireshark’s CLI equivalent. It ships with every Wireshark installation and is found in C:\Program Files\Wireshark\. Add that path to $env:PATH for convenience.

List available interfaces:

tshark -D

On Windows, interface names contain GUIDs; use the numeric index shown by -D:

1. \Device\NPF_{ABCD1234-...} (Ethernet)
2. \Device\NPF_{EFGH5678-...} (Wi-Fi)
3. \Device\NPF_Loopback (Npcap Loopback Adapter)

Basic capture:

tshark -i 1 -w capture.pcapng

With a BPF capture filter:

tshark -i 1 -f "tcp port 443" -w tls.pcapng

Stop after N packets:

tshark -i 1 -c 1000 -w capture.pcapng

Ring buffer — rotate every 100 MB, keep 5 files:

tshark -i 1 -b filesize:102400 -b files:5 -w capture.pcapng

Write to file and print decoded output simultaneously:

tshark -i 1 -w capture.pcapng -P

dumpcap

dumpcap is the actual capture engine that both Wireshark and tshark call internally. It is the right tool for long-running headless captures: it skips protocol dissection entirely, which reduces CPU overhead and the attack surface from malformed packets.

# List interfaces
dumpcap -D

# Capture to file
dumpcap -i 1 -w capture.pcapng

# Ring buffer: 10 files × 50 MB
dumpcap -i 1 -b filesize:51200 -b files:10 -w capture.pcapng

# BPF capture filter
dumpcap -i 1 -f "not tcp port 22" -w filtered.pcapng

Prefer dumpcap over tshark -w for automated or long-running captures. Use tshark -r afterward to analyze the saved file.

Tool Comparison

Feature netsh trace pktmon NetEventSession Wireshark tshark / dumpcap
Requires installation No No No Yes (+ Npcap) Yes (+ Npcap)
Available since Windows 7 Windows 10 2004 Windows 8.1 / Server 2012 R2 Any Any
Output format etl → etl2pcapng etl → etl2pcap etl → etl2pcapng pcapng pcapng
Capture filters Yes (ETW-style) Yes (BPF-like) Yes Yes (BPF) Yes (BPF)
Display filters No No No Yes tshark only
Packet drop analysis No Yes No No No
Multi-layer capture No Yes No No No
Loopback capture No No No Yes (Npcap) Yes (Npcap)
Raw 802.11 frames No No No Yes (Npcap) Yes (Npcap)
Remote capture Via PSSession Via PSSession Native PSSession No No
GUI No No No Yes No
Ease of use Simple Moderate Verbose Simple Simple

Use netsh trace or pktmon when you cannot install software and need to capture on a locked-down or remote Windows host via PowerShell.

Use pktmon specifically when you need packet drop analysis or per-component stack visibility to diagnose where traffic is being lost.

Use NetEventSession when you need scripted or remote capture with fine-grained ETW provider control from PowerShell.

Use Wireshark for interactive analysis with GUI filtering and protocol dissection.

Use tshark or dumpcap for CLI capture on a workstation where Npcap/Wireshark are installed, or for automated captures — prefer dumpcap for long-running captures (lower overhead), tshark when you also want live decoding.

Workflow: Capture Remotely and Analyze Locally

A common scenario: capture on a remote Windows host, then analyze on your local machine with Wireshark or tshark.

# 1. Start capture on remote host
Invoke-Command -ComputerName target -ScriptBlock {
    pktmon filter add -p 443
    pktmon start --capture --file-name C:\temp\capture.etl
}

# 2. Wait for traffic of interest, then stop
Invoke-Command -ComputerName target -ScriptBlock {
    pktmon stop
    pktmon etl2pcap C:\temp\capture.etl --out C:\temp\capture.pcapng
}

# 3. Copy pcapng to local machine
Copy-Item -FromSession (New-PSSession -ComputerName target) `
    -Path "C:\temp\capture.pcapng" -Destination ".\capture.pcapng"

# 4. Analyze locally
tshark -r capture.pcapng -Y 'tls.handshake.type == 1' -T fields -e tls.handshake.extensions_server_name

Key takeaways

References


Related course pages: Capturing network traffic · tshark on the command line · Analyzing traffic with Wireshark

🛠️ Maintenance note: Windows tooling moves — pktmon gained native pcapng output around Windows 11/Server 2022, and netsh trace is the legacy path; Microsoft Network Monitor and Message Analyzer are both deprecated. Verify the Npcap version, the winget package ID, and the Microsoft Learn links each term, since Microsoft reorganizes those docs frequently.