如何在 powershell 中迭代 JSON 数组

Gre*_*ian 5 powershell

如何迭代转换为PSCustomObjectwith的 JSON 数组ConvertFrom-JSON?使用foreach不起作用。

$jsonArray ='[{"privateKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\key.pem"},
{"publicKeyLocation" : "C:\\ProgramData\\docker\\certs.d\\cert.pem"},
{"publicKeyCALocation" : "C:\\ProgramData\\docker\\certs.d\\ca.pem"}]'
$json = convertfrom-json $jsonArray
$json | foreach {$_}
Run Code Online (Sandbox Code Playgroud)

退货

privateKeyLocation
------------------
C:\ProgramData\docker\certs.d\key.pem
Run Code Online (Sandbox Code Playgroud)

枚举器虽然说数组有 3 个成员

>$json.Count
3
Run Code Online (Sandbox Code Playgroud)

The*_*ian 2

您遇到的问题并不特定于 JSON 数组,它与默认情况下如何显示数组中的自定义对象有关。最简单的答案是将其通过管道传输Format-List(或FL简称)。

PS C:\Users\TMTech> $JSON|FL


privateKeyLocation : C:\ProgramData\docker\certs.d\key.pem

publicKeyLocation : C:\ProgramData\docker\certs.d\cert.pem

publicKeyCALocation : C:\ProgramData\docker\certs.d\ca.pem
Run Code Online (Sandbox Code Playgroud)

除此之外,当 PowerShell 输出对象数组时,它显示的列基于数组中第一个对象的属性。在您的情况下,该对象有一个名为“privateKeyLocation”的属性,因此这是唯一出现的列,并且由于其他两个对象没有该属性,因此不会为它们显示任何内容。如果您想将其保留为表格,您可以收集所有潜在属性,并将它们添加到具有空值的第一个项目中,这样您就可以将其显示为表格,但它看起来仍然不太好:

$json|%{$_.psobject.properties.name}|select -Unique|?{$_ -notin $json[0].psobject.Properties.Name}|%{Add-Member -InputObject $JSON[0] -NotePropertyName $_ -NotePropertyValue $null}
Run Code Online (Sandbox Code Playgroud)

然后你可以输出为表格并获取所有内容:

PS C:\Users\TMTech> $json

privateKeyLocation                    publicKeyLocation                      publicKeyCALocation                 
------------------                    -----------------                      -------------------                 
C:\ProgramData\docker\certs.d\key.pem                                                                            
                                      C:\ProgramData\docker\certs.d\cert.pem                                     
                                                                             C:\ProgramData\docker\certs.d\ca.pem
Run Code Online (Sandbox Code Playgroud)

编辑:在这种情况下获取每个对象的值很棘手,因为每个对象要扩展的属性不断变化。我能想到有两种方法可以做到这一点,我认为正确的方法是什么,然后是简单的方法。正确的方法是确定要扩展的属性,然后直接引用该属性:

$JSON |%{
    $PropName = $_.PSObject.Properties.Name
    $_.$PropName
}
Run Code Online (Sandbox Code Playgroud)

这会做你想要的,但我认为更容易的是通过管道传递到Format-List,然后Out-String将整个内容用括号括起来,分割成新行并替换所有内容:,直到留下你想要的路径。

($JSON|FL|Out-String) -split '[\r\n]+' -replace '(?m)^.+ : '|?{$_}
Run Code Online (Sandbox Code Playgroud)