如何从系统账户获取远程桌面服务(RDS)当前会话的用户名?
问题描述
在RDS(远程桌面服务)环境中,以系统账户(NT Authority\SYSTEM)运行PowerShell脚本时,需要准确获取当前登录的用户会话对应的用户名。现有常用方案均存在不可靠性:
- 获取
explorer.exe进程所属用户:RDS中可能存在多个该进程,无法区分所属会话; - 使用
quser/query session工具:返回的Chevron标记(>`)有时会错误指向非当前的“活跃”用户; - 查询
Win32_Computersystem:无法满足多活跃会话场景下的精准识别需求。
RDS环境可能同时存在多个活跃会话(含RDP、ICA连接方式),例如UserA、UserB、UserC均处于活跃状态,当以UserB身份登录时,脚本需返回UserB,而非系统账户或其他用户。
解决方案:精准获取当前会话用户名
通过进程会话ID关联登录用户的方式,可规避现有方案的缺陷,实现多活跃会话场景下的精准识别。
实现脚本
# 获取当前脚本进程的会话ID $currentSessionId = (Get-Process -Id $PID).SessionId # 查询会话ID对应的登录会话记录 $logonSession = Get-CimInstance Win32_LogonSession | Where-Object { $_.SessionId -eq $currentSessionId } if ($logonSession) { # 关联登录会话与用户账户 $userAccount = Get-CimInstance -Query "ASSOCIATORS OF {Win32_LogonSession.LogonId='$($logonSession.LogonId)'} WHERE ResultClass=Win32_UserAccount" if ($userAccount) { # 输出用户名,如需完整域名格式可改为 "$($userAccount.Domain)\$($userAccount.Name)" Write-Output $userAccount.Name } else { Write-Error "无法找到会话对应的用户账户" } } else { Write-Error "无法获取当前进程的会话信息" }
核心原理
- 定位会话ID:脚本自身进程的
SessionId即为其运行所在的用户会话ID(即便以系统账户身份启动,只要在用户会话中运行,该ID就对应用户的交互会话); - 关联登录会话:通过
Win32_LogonSession类查询该会话ID对应的系统登录记录; - 绑定用户账户:利用WMI关联查询机制,将登录记录与
Win32_UserAccount对象绑定,提取目标用户名。
适用场景
- 多活跃会话的RDS环境(支持RDP、ICA等多种连接方式);
- 以系统账户身份在用户会话中运行的脚本(如任务计划指定用户会话执行、通过
psexec -s在用户会话启动脚本等)。
内容的提问来源于stack exchange,提问作者Captain_Planet
相关产品推荐
相关产品推荐

