PowerShell调用quser获取用户会话状态无法单独提取Disc/Active值咨询
问题根因
你写死固定字符偏移量截取字段的逻辑存在缺陷:quser.exe的输出列宽会随用户名长度、会话ID位数动态调整,固定从第46位截取6个字符的规则经常出现截位偏差,要么混入相邻字段的字符、要么残留多余空格,最终拿到的State值不是纯净的Disc/Active,自然无法直接用于条件判断。
修复方法
放弃固定偏移量解析逻辑,改用正则表达式按字段规则匹配提取,可适配所有列宽变化的场景,准确拿到纯净的状态值。
修复后的可直接运行脚本如下,输出结果和quser原生输出完全一致,且State字段可直接用于if判断:
[cmdletbinding()] param( [String[]]$ComputerNames = $env:COMPUTERNAME ) foreach ($Computer in $ComputerNames) { $stringOutput = quser /server:$Computer 2>$null If (!$stringOutput) { Write-Warning "Unable to retrieve quser info for `"$Computer`"" continue } # 跳过quser输出的表头行 $dataLines = $stringOutput | Select-Object -Skip 1 ForEach ($line in $dataLines) { # 正则按字段规则匹配,自动适配列宽变化 if ($line -match '^\s?(\S+)\s+(\S*)\s+(\d+)\s+(\w+)\s+(\S+)\s+(.+)$') { $username = $matches[1] $sessionName = $matches[2] $sessionId = $matches[3] $state = $matches[4] $idleRaw = $matches[5].Replace('+', '.') if ($idleRaw -eq '.' -or $idleRaw -eq 'none') { $idleTime = $null } else { $idleTime = [timespan]$idleRaw } $logonTime = [datetime]$matches[6] $sessionInfo = [PSCustomObject]@{ Username = $username SessionName = $sessionName ID = $sessionId State = $state IdleTime = $idleTime LogonTime = $logonTime } # 可直接在此处做状态判断 if ($sessionInfo.State -eq 'Disc') { # 断开状态会话的自定义处理逻辑写在此处 } $sessionInfo } } }
使用说明
- 脚本输出对象的
State属性只会返回纯净的Disc(断开连接)、Active(活跃)值,无多余空格或杂项字符,可直接用于条件判断,例:$discSessions = <脚本返回结果> | Where-Object State -eq 'Disc' - 正则匹配规则自动适配不同长度的用户名、1位/2位会话ID、不同格式的空闲时间值,不会出现原脚本的截位错误
- 补充了原脚本查询目标机器失败时的跳过逻辑,避免空值执行后续代码触发报错
内容的提问来源于stack exchange,提问作者Damen Priddy
相关产品推荐
相关产品推荐

