PowerShell中如何完整捕获ScriptBlock内query user的全部输出?
问题解答
1. 如何正确捕获query user的全部内容?
query user是外部CMD命令,其输出可能包含被PowerShell归类到错误流的内容,默认不会被捕获。要完整获取所有输出,需要合并所有流并将结果转为完整字符串,最后通过自定义对象封装返回:
$invokeResult = Invoke-Command -ComputerName PC1 -ScriptBlock { # 合并所有输出流并转成完整字符串,避免内容分散或丢失 $fullUserInfo = query user *>&1 | Out-String $osVersion = [Environment]::OSVersion # 用自定义对象封装需要返回的所有数据 [PSCustomObject]@{ UserSessionInfo = $fullUserInfo OSVersion = $osVersion } } # 查看完整的用户会话信息 $invokeResult.UserSessionInfo
通过这种方式,你就能拿到query user的全部输出,包括所有用户行和表头。
2. 所用的两种方法是否为标准做法?
你使用的两种方法都不是返回多结果的标准做法:
- 直接在ScriptBlock内赋值变量(
$user = query user):这种写法会让query user的输出直接作为ScriptBlock的输出返回,而非返回变量本身。Invoke-Command会收集ScriptBlock中所有未被捕获的输出,所以你得到的是query user的输出流加上最后一条命令的结果(OS版本),并非两个变量的完整值。 - 点源ScriptBlock:点源仅作用于当前会话的作用域,而Invoke-Command的执行在远程独立会话中,点源无法让远程变量同步到本地,远程输出仍会按流返回,无法解决内容丢失问题。
标准做法是在ScriptBlock内用自定义对象封装所有需要返回的数据,让Invoke-Command返回一个包含所有信息的结构化对象,这样能精准获取每一项内容。
3. 是否因为query user不是PowerShell命令导致无法保留完整对象?
是的,核心原因有两点:
query user是外部CMD命令,输出为纯文本而非PowerShell结构化对象。PowerShell处理外部命令输出时,会将文本按行拆分为字符串数组,且部分被识别为“错误”的输出行(比如某些状态提示)会被放到错误流,默认不会包含在返回结果中,导致内容丢失。- 而PowerShell原生命令(比如
Get-CimInstance Win32_ComputerSystem)返回的是结构化对象,所有属性都会被完整序列化并传输,不会出现内容截断或丢失的问题。
内容的提问来源于stack exchange,提问作者DrixlRey
相关产品推荐
相关产品推荐

