PowerShell中ConvertFrom-Json直接管道与临时变量输出差异问询
为何ConvertFrom-Json直接管道与赋值给变量后管道输出不同?
问题复现
以下两段PowerShell代码逻辑看似一致,但输出结果完全不同:
代码示例
$json = '[{"name": "george", "psw64": "AMnd8BFdd8BFd" }, {"name": "lucy", "psw64": "AQ8BFdERjHoAw" } ] ' # a) 输出异常 convertfrom-json $json | foreach-object { $_.name + ': '+ $_.psw64 } # b) 输出符合预期 $data = convertfrom-json $json $data | foreach-object { $_.name + ': '+ $_.psw64 }
输出对比
a)的输出:
george lucy : AMnd8BFdd8BFd AQ8BFdERjHoAw
b)的输出:
george: AMnd8BFdd8BFd lucy: AQ8BFdERjHoAw
使用PowerShell版本:5.1.22000.832
核心原因
这是PowerShell 5.1中ConvertFrom-Json的管道枚举行为差异导致的:
- 当直接将
ConvertFrom-Json的结果传入管道时,PowerShell会对返回的PSCustomObject数组执行深度枚举——它会遍历数组中每个对象的所有属性,将每个属性值单独作为管道的输出项,而非输出整个PSCustomObject。此时ForEach-Object处理的是单个属性值而非完整对象,自然无法同时访问name和psw64,导致拼接逻辑失效。 - 当把结果赋值给变量
$data后,数组被视为一个完整的集合对象,管道传递时会逐个输出数组中的每个PSCustomObject,此时ForEach-Object能正确访问每个对象的name和psw64属性,完成字符串拼接。
你可以通过Get-Member验证这个差异:
- 直接管道:
convertfrom-json $json | Get-Member会显示输出的是String类型(即属性值的类型) - 变量管道:
$data | Get-Member会显示输出的是PSCustomObject类型
解决方法
要让直接管道的行为和变量管道一致,需要强制PowerShell不深度枚举ConvertFrom-Json的结果,有两种常用方式:
- 用括号包裹结果,强制将其视为单个集合对象:
(convertfrom-json $json) | foreach-object { $_.name + ': '+ $_.psw64 }
- 在结果前加逗号,创建单元素数组,避免深度枚举:
,(convertfrom-json $json) | foreach-object { $_.name + ': '+ $_.psw64 }
内容的提问来源于stack exchange,提问作者Babla
相关产品推荐
相关产品推荐

