powershell 可通过分析事件日志中 id 24(会话断开)统计 rdp 断开次数,需启用 microsoft-windows-terminalservices-localsessionmanager/operational 日志、以管理员权限运行,并用 get-winevent 筛选指定时段的 id 24 事件,同时排除 id 25 注销事件干扰。
powershell 本身不直接记录 windows 终端(如 remote desktop services 或 windows rdp 客户端)的“断开连接次数”,但可以通过分析系统日志中与远程桌面会话状态变化相关的事件,间接统计特定时间段内用户会话被断开的次数。关键在于识别 事件 id 24(会话断开) 和 事件 id 25(会话注销)(部分场景下也需关注 id 41、id 1000 等),它们通常出现在 microsoft-windows-terminalservices-localsessionmanager/operational 日志中。
确认并读取终端服务会话日志
Windows 默认启用该日志,但可能未启用详细操作日志。请先确保日志通道存在且有权限读取:
- 运行 Get-WinEvent -ListLog "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" -ErrorAction SilentlyContinue,若返回结果说明日志可用;
- 若提示“日志不存在”,需在“事件查看器 → 应用程序和服务日志 → Microsoft → Windows → TerminalServices-LocalSessionManager → Operational”右键启用日志;
- 普通用户可能无权读取此日志,建议以管理员身份运行 PowerShell,或提前为当前用户授予读取权限(通过 wevtutil sl 命令配置)。
筛选指定时间段内的会话断开事件(ID 24)
事件 ID 24 表示用户主动断开或网络中断导致的会话断开(非注销),是统计“网络断开次数”的核心依据。使用 Get-WinEvent 配合时间范围和过滤哈希表:
- 定义时间范围:$startTime = (Get-Date).AddHours(-24); $endTime = Get-Date;
- 执行查询:Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'; ID=24; StartTime=$startTime; EndTime=$endTime} -ErrorAction SilentlyContinue | Measure-Object | Select-Object -ExpandProperty Count;
- 如需查看具体断开记录,可去掉 Measure-Object,添加 Select TimeCreated, Id, LevelDisplayName, Message 查看上下文(例如是否含“网络错误”、“连接丢失”等关键词)。
排除误计:区分断开(Disconnect)与注销(Logoff)
事件 ID 25(Logoff)代表用户主动注销或会话超时清理,不应计入“网络断开”。若需更精准统计,可联合分析:
Windows 命令行编码与兼容规范。涵盖 GBK/UTF-8 编码、PowerShell/pwsh 互操作、Python/Node.js、Git 配置及代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。
- 对比 ID 24 与 ID 25 的时间戳和会话 ID(Properties[0].Value 通常是 SessionId),判断同一会话是否先断开后注销;
- 过滤掉紧随 ID 25 后发生的 ID 24(间隔
- 对高并发环境,建议导出原始事件对象后用 Where-Object 进一步按 Message 字段匹配“network error”、“connection lost”、“timeout”等字符串增强准确性。
封装为可复用脚本(带参数支持)
以下是一个轻量脚本示例,保存为 Count-RDSDisconnects.ps1,支持自定义时间窗口与日志路径:
$params = @{
LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
ID = 24
StartTime = (Get-Date).AddMinutes(-30)
EndTime = Get-Date
ErrorAction = 'SilentlyContinue'
}
$disconnects = Get-WinEvent @params | Where-Object {
$_.Message -match 'network|lost|timeout|disconnected' -or $_.Message -notmatch 'logoff|cleanup'
}
Write-Host "过去30分钟内检测到 $($disconnects.Count) 次疑似网络断开"
运行前需解除策略限制:Set-ExecutionPolicy RemoteSigned -Scope CurrentUser;实际部署时建议加入错误处理和日志输出功能。










