PowerShell中过滤PSCustomObject实现用户会话状态精准判断的技术求助
PowerShell: 精准匹配用户与对应会话状态的解决方案
我明白你的问题所在——你之前用-match的方式是在整个结果数组里模糊查找字符串,而不是针对单个会话对象的属性做关联判断,所以会出现“只要数组里有目标用户和对应状态就触发”的情况,没法精准对应到同一个用户的会话状态。
下面给你几种可行的解决方案,从简单到灵活:
方案1:直接筛选符合双条件的会话
最直接的方式是用Where-Object同时过滤用户名和会话状态,确保是同一个对象满足两个条件:
# 检查tnejtek的Active会话 if ($queryResults | Where-Object { $_.USERNAME -eq "tnejtek" -and $_.STATE -eq "Active" }) { Write-Host "tnejtek is connected" } # 检查xxx的Disconnected会话 elseif ($queryResults | Where-Object { $_.USERNAME -eq "xxx" -and $_.STATE -eq "Disconnected" }) { Write-Host "user xxx is disconnected" } else { Write-Host "No matching session found" }
方案2:先定位用户会话,再判断状态
如果需要对同一个用户的不同状态做更多处理,先单独取出该用户的会话对象会更清晰:
# 先获取tnejtek的所有会话(通常一个用户只有一个会话) $userSession = $queryResults | Where-Object { $_.USERNAME -eq "tnejtek" } # 先判断用户是否存在会话 if ($userSession) { switch ($userSession.STATE) { "Active" { Write-Host "tnejtek is connected" } "Disconnected" { Write-Host "user tnejtek is disconnected" } default { Write-Host "tnejtek's session state is $($userSession.STATE)" } } } else { Write-Host "tnejtek has no active sessions on this server" }
方案3:批量处理多个用户(推荐)
如果需要同时检查多个用户的状态,用循环遍历所有会话会更高效,还能自动忽略系统默认会话(比如console、rdp-tcp这些非真实用户的会话):
foreach ($session in $queryResults) { # 跳过系统会话(用户名是空或纯数字的) if ([string]::IsNullOrWhiteSpace($session.USERNAME) -or $session.USERNAME -match '^\d+$') { continue } # 根据用户名和状态输出对应信息 if ($session.USERNAME -eq "tnejtek" -and $session.STATE -eq "Active") { Write-Host "tnejtek is connected" } elseif ($session.USERNAME -eq "xxx" -and $session.STATE -eq "Disconnected") { Write-Host "user xxx is disconnected" } # 可以添加更多用户的判断条件 }
为什么你的原始代码不工作?
简单说,$queryResults -match "tnejtek"会返回所有包含"tnejtek"字符串的会话对象(这里就是tnejtek的那个会话),而$queryResults -match "Active"会返回所有包含"Active"的对象(同样是tnejtek的会话)。但用-and连接时,PowerShell是在判断“这两个结果是否都不为空”,而不是“是否存在一个对象同时满足两个条件”——虽然在这个案例里结果可能碰巧正确,但如果数组里有另一个用户的Active会话,你的代码会误判。
内容的提问来源于stack exchange,提问作者Tomáš Nejtek
相关产品推荐
相关产品推荐

