You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell获取用户数量结果不准确的原因及修正方案咨询

问题原因与解决方案

一、错误结果的内部机制原因

你使用的Win32_LogonSession和Win32_LoggedOnUser这两个WMI类,核心问题出在登录会话的清理逻辑上:

  • 用户注销交互会话后,只要还有以该用户身份运行的后台进程(比如未关闭的后台程序、挂起的服务进程)存在,系统不会立即销毁对应的登录会话对象。
  • WMI通过读取这些未销毁的登录会话判定用户“在线”,但实际上用户已经退出了交互环境。
  • 而服务器管理器的远程桌面服务模块,直接对接RD服务的会话管理数据,它会区分用户是否处于活跃交互状态——哪怕有残留进程,只要用户完成注销操作,RD服务就会标记该会话为离线,这就是两者结果不一致的根本原因。

二、准确获取用户数量的修正方案

方案1:使用RD服务专用命令(推荐)

直接调用远程桌面服务的PowerShell模块命令,和服务器管理器的数据源完全一致,结果最准确:

$computer = 'computername'
# 获取所有活跃的远程桌面用户会话(可根据需求调整SessionState过滤条件)
$activeUsers = Get-RDUserSession -ConnectionBroker $computer | Where-Object { $_.SessionState -eq 'Active' }
$anzahl_user = $activeUsers.Count

注:该命令需要服务器安装远程桌面服务角色,且PowerShell会话拥有足够权限。

方案2:使用RD专用WMI类

如果无法使用RD模块,可直接查询专门针对远程桌面会话的WMI类Win32_RDMSession:

$computer = 'computername'
# SessionState=2代表活跃会话,其他状态可根据需求过滤
$users = Get-WmiObject -ComputerName $computer -Class Win32_RDMSession | Where-Object { $_.SessionState -eq 2 }
$anzahl_user = $users.Count

方案3:对原有WMI结果补充过滤

如果必须沿用原有逻辑,可通过检查会话的活跃交互进程来过滤无效会话:

$computer = 'computername'
$users = Get-WmiObject Win32_LogonSession -Computer $computer -Filter 'LogonType=2 or LogonType=10' | ForEach-Object {
    $logonId = $_.LogonId
    # 检查该登录会话是否有活跃的交互进程(以explorer.exe为标志)
    $hasActiveProcess = Get-WmiObject -ComputerName $computer -Query "SELECT * FROM Win32_Process WHERE LogonId='$logonId' AND Name='explorer.exe'"
    if ($hasActiveProcess) {
        Get-WmiObject -ComputerName $computer -Query "Associators of {Win32_LogonSession.LogonId=$logonId} Where AssocClass=Win32_LoggedOnUser Role=Dependent" | Select-Object -ExpandProperty Name
    }
}
$anzahl_user = $users.Count

注:该方案依赖explorer.exe作为交互活跃的标志,部分特殊场景可能不适用。

内容的提问来源于stack exchange,提问作者NinaGr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 10:34:50