如何通过Powershell获取RDP服务器自启用以来的全部会话历史记录
RDP服务器全量会话历史PowerShell查询方案
实现原理
你之前使用的qwinsta、quser、query user工具仅支持查询当前存活的会话,无法获取已注销的历史会话数据。全量会话数据需从Windows系统内置的事件日志中提取:
- RDP会话的全生命周期事件都记录在
Microsoft-Windows-TerminalServices-LocalSessionManager/Operational日志路径下,事件ID对应如下:- 事件ID 21:会话登录成功
- 事件ID 23:会话断开连接
- 事件ID 24:会话注销结束
- 事件ID 112:RDP连接建立成功
- 如需交叉验证登录来源IP等信息,可以关联安全日志中的4624(登录成功)事件。
可直接运行的实现代码
注意:需以管理员权限启动PowerShell运行,否则无法读取系统事件日志
# 配置查询时间范围,可自行修改 $StartTime = (Get-Date).AddDays(-30) # 默认查近30天,可调整为更早时间 $EndTime = Get-Date $serverName = $env:COMPUTERNAME # 提取RD会话管理日志 $rdpEvents = Get-WinEvent -FilterHashTable @{ LogName = "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" ID = 21,23,24,112 StartTime = $StartTime EndTime = $EndTime } -ErrorAction SilentlyContinue # 按会话ID+用户名分组整理数据 $sessionData = @{} foreach ($event in $rdpEvents) { $sid = $event.Properties[0].Value $username = $event.Properties[1].Value if (-not $username) { continue } $sessionKey = "$sid-$username" if (-not $sessionData.ContainsKey($sessionKey)) { $sessionData[$sessionKey] = [PSCustomObject]@{ SESSIONNAME = $null USERNAME = $username ID = $sid STATE = $null DEVICE = $null LAST_LOGIN = $null LastEventTime = $event.TimeCreated } } # 更新最近操作时间和状态 if ($event.TimeCreated -gt $sessionData[$sessionKey].LastEventTime) { $sessionData[$sessionKey].LastEventTime = $event.TimeCreated switch ($event.Id) { 21 { $sessionData[$sessionKey].STATE = "Active" $sessionData[$sessionKey].LAST_LOGIN = $event.TimeCreated $sessionData[$sessionKey].SESSIONNAME = $event.Properties[2].Value } 23 { $sessionData[$sessionKey].STATE = "Disc" } 24 { $sessionData[$sessionKey].STATE = "LoggedOff" } 112 { $sessionData[$sessionKey].DEVICE = $event.Properties[3].Value } } } } # 输出格式对齐参考要求 Write-Host "`n$serverName`n" $sessionData.Values | Sort-Object ID | Format-Table SESSIONNAME,USERNAME,ID,STATE,DEVICE,LAST_LOGIN -AutoSize
输出说明
代码输出格式和你要求的参考格式完全对齐,包含字段:
- SESSIONNAME:会话连接名称,比如rdp-tcp#xx、console等
- USERNAME:登录用户名
- ID:会话ID
- STATE:会话状态,Active为活跃、Disc为断开、LoggedOff为已注销
- DEVICE:客户端设备名(如有)
- LAST_LOGIN:最近一次登录时间
如果需要仅导出指定状态的用户,可在输出前增加过滤逻辑,比如$sessionData.Values | Where-Object STATE -in "Active","Disc"即可仅展示当前未注销的会话。
内容的提问来源于stack exchange,提问作者Angel Adir
相关产品推荐
相关产品推荐

