批量查询CSV中主机用户登录状态的PowerShell脚本求助
批量查询远程机器登录用户的解决方案
问题分析
你当前的代码核心问题是:Import-CSV导入的每一行是对象而非纯字符串,$DeviceName是包含DeviceName属性的对象,直接传给query user /server会导致参数传递错误。同时需要将零散的查询结果结构化,才能方便导出和后续分析。
修正后的PowerShell脚本
以下脚本会批量处理CSV中的机器,捕获查询结果(含连接失败的情况),并导出为结构化的CSV文件:
# 导入机器列表CSV $machineList = Import-CSV C:\temp\1909-20221104.csv # 初始化数组存储最终结果 $results = @() foreach ($machine in $machineList) { $deviceName = $machine.DeviceName Write-Host "正在查询: $deviceName" try { # 执行query user命令,同时捕获标准输出和错误输出 $queryOutput = cmd /c query user /server "$deviceName" 2>&1 # 根据命令退出码判断查询是否成功 if ($LASTEXITCODE -eq 0) { # 跳过表头行,将文本输出转换为结构化对象 $userEntries = $queryOutput | Select-Object -Skip 1 | ForEach-Object { # 用逗号替换连续空格,再转换成CSV对象 $line = $_ -replace '\s{2,}', ',' | ConvertFrom-Csv -Header "用户名", "会话名", "ID", "状态", "空闲时间", "登录时间" [PSCustomObject]@{ 机器名 = $deviceName 用户名 = $line.用户名 会话ID = $line.ID 状态 = $line.状态 空闲时间 = $line.空闲时间 登录时间 = $line.登录时间 查询状态 = "成功" } } $results += $userEntries } else { # 记录查询失败的机器及原因 $results += [PSCustomObject]@{ 机器名 = $deviceName 用户名 = $null 会话ID = $null 状态 = $null 空闲时间 = $null 登录时间 = $null 查询状态 = "失败" 失败原因 = $queryOutput | Out-String } } } catch { # 捕获脚本执行异常,记录错误信息 $results += [PSCustomObject]@{ 机器名 = $deviceName 用户名 = $null 会话ID = $null 状态 = $null 空闲时间 = $null 登录时间 = $null 查询状态 = "异常" 失败原因 = $_.Exception.Message } } } # 将结果导出到UTF8编码的CSV文件 $results | Export-CSV -Path C:\temp\远程用户查询结果.csv -Encoding UTF8 -NoTypeInformation Write-Host "查询完成,结果已导出到C:\temp\远程用户查询结果.csv"
关键说明
- 变量修正:通过
$machine.DeviceName提取CSV中实际的机器名字符串,解决参数传递错误问题 - 结果结构化:把
query user的纯文本输出转换成PowerShell对象,方便后续筛选、排序 - 错误处理:捕获连接失败、命令执行错误等场景,记录失败原因,避免脚本中途中断
- 导出功能:最终结果导出为通用的CSV格式,包含所有机器的查询状态和用户明细
注意事项
- 运行脚本的账号需要拥有目标机器的远程管理权限
- 目标机器需开启远程服务(如TermService),且网络可达
- 若机器数量过多,可添加
Start-Sleep -Milliseconds 500控制查询频率,避免触发防护机制
内容的提问来源于stack exchange,提问作者Josh Langdon
相关产品推荐
相关产品推荐

