Windows 自带抓包神器 PktMon
前言
做网络排查的时候,大多数人的第一步是下载 Wireshark。它确实是行业标杆,但有时候你只需要快速看一下「这台机器到底在跟谁通信」「某个端口有没有流量」,为此装一个 200MB 的工具加上 Npcap 驱动,未免有点杀鸡用牛刀。
实际上,从 Windows 10 开始,系统就内置了一个命令行抓包工具 PktMon(Packet Monitor),路径就在:
C:\Windows\System32\pktmon.exe
不需要安装驱动,不需要额外配置,管理员权限的 CMD 打开就能用。
PktMon 是什么
PktMon 最早出现在 Windows Server 2019,后来被移植到 Windows 10/11。它基于 ETW(Event Tracing for Windows) 直接集成到 Windows 网络栈,这意味着:
- 零安装成本:不需要 Npcap、WinPcap 等第三方驱动
- 系统级视角:直接在内核层捕获流量,比应用层抓包更准确
- 锁定环境可用:企业管控策略禁止安装软件的场景下特别有用
- 开销低:ETW 机制本身就是为低开销诊断设计的
简单对比一下:
| 特性 | PktMon | Wireshark | netsh trace |
|---|---|---|---|
| 系统内置 | ✅ | ❌ | ✅ |
| GUI 界面 | ❌ | ✅ | ❌ |
| 输出格式 | ETL / PCAPNG | PCAP / PCAPNG | ETL |
| 上手难度 | 低 | 中 | 高 |
| 适用场景 | 快速抓包 | 深度分析 | 遗留追踪 |
一句话总结:PktMon 是 Windows 上「快速抓一把看看」的最佳选择,Wireshark 是「深入分析」的终极武器,两者配合使用效果最好。
基础用法:三行命令搞定抓包
打开 管理员 CMD(重要,普通权限不行),然后:
:: 1. 添加过滤器 —— 只抓 HTTPS 流量(端口 443)
pktmon filter add -p 443
:: 2. 开始抓包
pktmon start --capture
:: 3. 做你要排查的操作...然后停止
pktmon stop
抓包结果保存在当前目录的 PktMon.etl 文件中。ETL 是 Windows 原生的事件追踪格式,直接看不了。转成可读文本:
pktmon format PktMon.etl -o output.txt -x
-x 参数确保输出是人类可读的格式。如果需要丢到 Wireshark 里做深度分析:
pktmon pcapng PktMon.etl -o output.pcapng
这就是 PktMon 最经典的用法:先用 PktMon 快速抓包,需要深入分析时再转成 PCAPNG 丢给 Wireshark。
实用过滤器
PktMon 的过滤器是抓包前设置的,可以组合使用:
| 目标 | 命令 |
|---|---|
| 只抓 HTTPS | pktmon filter add -p 443 |
| 只抓特定 IP | pktmon filter add -d 54.236.120.233 |
| 只抓 TCP | pktmon filter add -t TCP |
| 指定网卡 | pktmon filter add -i [ID](用 pktmon list 查 ID) |
| 限制抓包数量 | 启动时加 -c 100 |
| 清除所有过滤器 | pktmon filter remove |
实时模式:不落盘直接看
如果只想快速看「当前有什么流量」,不需要存文件:
pktmon start --capture -m real-time
这会在终端实时显示:
- 时间戳
- 方向(Rx = 收 / Tx = 发)
- 源/目标 IP
- TCP 标志位
对于「这个应用到底在连什么」「DNS 请求发到哪了」这类问题,实时模式几秒钟就能给你答案。
实战场景
场景 1:排查应用连接慢
:: 过滤目标服务器 IP
pktmon filter add -d 10.0.1.50
pktmon start --capture -m real-time
:: 观察是否有重传、连接超时等模式
场景 2:检查后台静默连接
不设任何过滤器直接抓一分钟,你会惊讶于系统在后台有多少「悄悄通信」。
pktmon start --capture
:: 等一分钟
pktmon stop
pktmon format PktMon.etl -o bg-traffic.txt -x
翻一翻输出,你可能会发现 Windows 遥测、更新检查、OneDrive 同步、各种后台服务的连接——了解你的系统在「不用的时候」到底在干什么,本身就很有价值。
场景 3:在 Hyper-V / 虚拟化环境中抓包
PktMon 默认捕获 Wi-Fi、以太网和虚拟网卡的流量。在 Hyper-V 环境中,传统工具有时候抓不到虚拟交换机上的流量,PktMon 因为集成在系统网络栈里,天然支持这个场景。
进阶:用 PowerShell 脚本自动化网络监控
PktMon 是标准的 CLI 工具,天然适合用 PowerShell 做自动化。下面是一个实用的监控脚本示例——定时抓包、自动转换格式、按日期归档:
<#
.SYNOPSIS
PktMon 定时抓包监控脚本
.DESCRIPTION
每隔指定间隔自动运行一轮抓包,转换为 PCAPNG 格式并按日期归档。
适用于持续监控特定端口/IP 的流量模式。
#>
param(
[int]$CaptureDurationSec = 60, # 每轮抓包时长(秒)
[int]$IntervalSec = 300, # 两轮之间间隔(秒)
[int]$Rounds = 12, # 总轮数(12轮×5分钟=1小时)
[string]$OutputDir = "C:\PktMon-Captures",
[int]$FilterPort = 0, # 0 = 不过滤
[string]$FilterIP = "" # 空 = 不过滤
)
# 需要管理员权限
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Error "请以管理员身份运行此脚本"
exit 1
}
# 创建输出目录
$dateDir = Join-Path $OutputDir (Get-Date -Format "yyyy-MM-dd")
New-Item -ItemType Directory -Force -Path $dateDir | Out-Null
Write-Host "[PktMon Monitor] 开始监控" -ForegroundColor Cyan
Write-Host " 每轮抓包: ${CaptureDurationSec}s | 间隔: ${IntervalSec}s | 总轮数: $Rounds"
Write-Host " 输出目录: $dateDir"
# 设置过滤器
pktmon filter remove 2>$null | Out-Null
if ($FilterPort -gt 0) {
pktmon filter add -p $FilterPort | Out-Null
Write-Host " 过滤端口: $FilterPort" -ForegroundColor Yellow
}
if ($FilterIP -ne "") {
pktmon filter add -d $FilterIP | Out-Null
Write-Host " 过滤 IP: $FilterIP" -ForegroundColor Yellow
}
for ($i = 1; $i -le $Rounds; $i++) {
$timestamp = Get-Date -Format "HHmmss"
$etlFile = Join-Path $dateDir "capture_${timestamp}.etl"
$pcapFile = Join-Path $dateDir "capture_${timestamp}.pcapng"
Write-Host "`n[$i/$Rounds] $(Get-Date -Format 'HH:mm:ss') 开始抓包..." -ForegroundColor Green
# 启动抓包
pktmon start --capture --file-name $etlFile | Out-Null
Start-Sleep -Seconds $CaptureDurationSec
pktmon stop | Out-Null
# 转换为 PCAPNG
if (Test-Path $etlFile) {
pktmon pcapng $etlFile -o $pcapFile | Out-Null
$sizeKB = [math]::Round((Get-Item $pcapFile).Length / 1KB, 1)
Write-Host " 已保存: $pcapFile ($sizeKB KB)" -ForegroundColor Gray
# 可选:删除 ETL 原始文件节省空间
Remove-Item $etlFile -Force
}
# 最后一轮不等待
if ($i -lt $Rounds) {
Write-Host " 等待 ${IntervalSec}s 后进行下一轮..."
Start-Sleep -Seconds $IntervalSec
}
}
# 清理过滤器
pktmon filter remove 2>$null | Out-Null
Write-Host "`n[PktMon Monitor] 监控完成,共 $Rounds 轮" -ForegroundColor Cyan
Write-Host "抓包文件: $dateDir"
使用示例:
# 监控 HTTPS 流量,每 60 秒抓一轮,共 12 轮
.\PktMon-Monitor.ps1 -FilterPort 443 -CaptureDurationSec 60 -Rounds 12
# 监控特定 IP,每 5 分钟抓 30 秒
.\PktMon-Monitor.ps1 -FilterIP 10.0.1.50 -CaptureDurationSec 30 -IntervalSec 300
# 全量抓包 10 分钟(1 轮)
.\PktMon-Monitor.ps1 -CaptureDurationSec 600 -Rounds 1
这个脚本的思路很简单:定时 → 抓包 → 转格式 → 归档。你可以把它注册为 Windows Task Scheduler 任务,实现无人值守的网络流量采样。抓到的 PCAPNG 文件随时可以丢到 Wireshark 里做回溯分析。
💡 **提示**:如果只需要一次性快速抓包转 PCAP,社区也有更简单的脚本可以参考,比如 [redhand.io/pcap_windows](https://redhand.io/pcap_windows) 提供的单次抓包脚本。
PktMon vs Wireshark:不是替代,是互补
明确一点:PktMon 不是 Wireshark 的替代品。
PktMon 没有 GUI,没有协议深度解码,没有流量可视化。它的定位是:
- ✅ 快速抓包看个大概
- ✅ 不能装软件的锁定环境
- ✅ 脚本化/自动化诊断
- ✅ 虚拟化环境
- ✅ 作为 Wireshark 的「前端采集器」
最佳实践是 PktMon 抓包 → 转 PCAPNG → Wireshark 分析,两者各司其职。
小结
| 你需要... | 用什么 |
|---|---|
| 快速看看某个端口有没有流量 | PktMon |
| 排查 TLS 握手失败的具体原因 | Wireshark |
| 在客户服务器上抓包(不能装软件) | PktMon |
| 自动化脚本定期采集网络数据 | PktMon |
| 分析复杂的协议交互 | Wireshark |
下次排查网络问题,不妨先试试 pktmon start --capture -m real-time,也许三行命令就够了。
参考链接
- Packet Monitor (Pktmon) 概览 - Microsoft Learn — 官方主文档
- pktmon 命令参考 - Microsoft Learn — 完整命令语法
- PktMon 命令格式与过滤器 - Microsoft Learn — 过滤器详解
- Packet Monitor Win32 API - Microsoft Learn — 编程接口文档
- Windows Admin Center 中的 Packet Monitoring 扩展 — GUI 方式使用 PktMon