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

PowerShell查询锁定用户会话:过滤无效结果与解析问题求助

问题1:过滤无用户的计算机并仅返回匹配用户的会话

原代码问题点

  1. 匹配到"No User exists for *"时用break会直接终止整个遍历循环,应该跳过当前计算机而非停止全部任务
  2. 条件判断的括号层级混乱,导致部分逻辑分支无法正确执行
  3. 未处理query user命令执行失败的场景(比如计算机离线、权限不足)

修正后的代码

$computers = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name
$total = $computers.Count
$counter = 0
$stringToMatch = "No User exists for"
$lockedOutUser = 'rdiring'

foreach ($computer in $computers) {
    $counter++
    $percentComplete = ($counter / $total) * 100
    Write-Progress -Activity "Processing computers" -Status "Computer $counter of $total" -PercentComplete $percentComplete
    
    try {
        # 捕获命令执行的错误,避免中断循环
        $quserResult = query user /server:$computer 2>&1
        Start-Sleep -Milliseconds 50

        # 检查是否无用户或命令执行失败
        if ($quserResult -match $stringToMatch -or $quserResult -is [System.Management.Automation.ErrorRecord]) {
            continue
        }

        # 解析输出为CSV对象
        $quserRegex = $quserResult | ForEach-Object { $_ -replace '\s{2,}', ',' }
        $quserObject = $quserRegex | ConvertFrom-Csv

        # 筛选目标用户会话并输出
        $userSession = $quserObject | Where-Object { $_.USERNAME -eq $lockedOutUser }
        if ($userSession) {
            [PSCustomObject]@{
                ComputerName = $computer
                UserName     = $userSession.USERNAME
                SessionID    = $userSession.ID
                SessionState = $userSession.STATE
                LogonTime    = $userSession.'LOGON TIME'
            }
        }
    }
    catch {
        continue
    }
}

关键优化点

  • 用2>&1捕获命令的错误输出,判断计算机是否无法连接
  • 匹配无用户提示时用continue跳过当前计算机,不输出冗余信息
  • 将结果封装为自定义对象,输出格式更规范易读
  • 修正条件层级,确保逻辑分支正确执行

问题2:修复query user解析代码输出为空的问题

原代码问题点

  1. 读取计算机列表到$names后立刻赋值为空数组,导致循环没有数据可处理
  2. 仅匹配表头行,完全忽略了实际的用户会话数据行
  3. -errorAction silentlyContinue写法错误,无法生效
  4. 用-split '\s+'解析数据行时,会因空的SESSIONNAME列导致字段错位

修正后的代码

# 定义输入输出路径
$InputFile = "C:\path\to\computers.txt"
$OutputFile = "C:\path\to\session_results.csv"

# 读取计算机列表,避免清空
$computerNames = Get-Content $InputFile
$sessionResults = @()

foreach ($name in $computerNames) {
    try {
        # 捕获错误输出,跳过无法连接的计算机
        $Lines = @(query user /server:$name 2>&1)
        
        # 跳过命令执行失败或无用户的情况
        if ($Lines -match "No User exists for" -or $Lines -is [System.Management.Automation.ErrorRecord]) {
            continue
        }

        # 跳过表头行,处理数据行
        $dataLines = $Lines | Select-Object -Skip 1
        foreach ($Line in $dataLines) {
            # 用正则匹配数据行,兼容SESSIONNAME为空的情况
            if ($Line -match '^(\S+)\s+(.*?)\s+(\d+)\s+(\S+)\s+(\S+)\s+(.*)$') {
                $sessionResults += [PSCustomObject]@{
                    SERVER       = $name
                    USERNAME     = $matches[1]
                    SESSIONNAME  = $matches[2].Trim()
                    ID           = $matches[3]
                    STATE        = $matches[4]
                    IDLE_TIME    = $matches[5]
                    LOGON_TIME   = $matches[6]
                }
            }
        }
    }
    catch {
        continue
    }
}

# 导出结果到CSV
$sessionResults | Export-Csv -Path $OutputFile -NoTypeInformation

关键修复点

  • 保留读取的计算机列表,用$computerNames存储,避免覆盖
  • 用Select-Object -Skip 1跳过表头,处理实际数据行
  • 采用正则表达式匹配数据行,解决空SESSIONNAME导致的字段错位问题
  • 单独用$sessionResults收集结果,避免和计算机列表变量混淆
  • 正确处理命令执行错误,跳过无法访问的计算机

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 13:16:19