在PowerShell中正确初始化JSON时出现问题

在PowerShell中正确初始化JSON时出现问题,json,powershell,Json,Powershell,我很难理解JSON在PowerShell中是如何工作的。。。我想创建并实现一个JSON,但我认为我做错了什么 此代码不起作用: $json = @" { "Volume" : [ ] } "@ | ConvertFrom-Json | Select-Object -Expand Volume foreach ($i in 0..2) { $blockvalue = @" { "UUID&qu

我很难理解JSON在PowerShell中是如何工作的。。。我想创建并实现一个JSON,但我认为我做错了什么

此代码不起作用:

$json = @"
{ 
    "Volume" : [
    ]
}
"@ | ConvertFrom-Json | Select-Object -Expand Volume


foreach ($i in 0..2) {
    $blockvalue = @"
        { "UUID" : "uuid-$($i)",
            "Details" : [ { "Name" : "Name-$($i)" }, { "SVM" : "SVM-$($i) " }, { "LastSnapshot" : "snap-$($i)" }, { "Date" : "date-$($i) " } ] }
"@
    $json += (ConvertFrom-Json -InputObject $blockvalue)
}



$json | Select UUID,@{Name="Volume";E={$_.Details | Select -Expand Name}},@{Name="SVM";E={$_.Details | Select -Expand SVM}},@{Name="Date";E={$_.Details | Select -Expand Date}},@{Name="LastSnapshot";E={$_.Details | Select -Expand LastSnapshot}} | FT
输出:

Method invocation failed because [System.Management.Automation.PSObject] does 
not contain a method named 'op_Addition'.
At line:14 char:5
+     $json += (ConvertFrom-Json -InputObject $blockvalue)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], Runtime 
   Exception
    + FullyQualifiedErrorId : MethodNotFound
 
Method invocation failed because [System.Management.Automation.PSObject] does 
not contain a method named 'op_Addition'.
At line:14 char:5
+     $json += (ConvertFrom-Json -InputObject $blockvalue)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], Runtime 
   Exception
    + FullyQualifiedErrorId : MethodNotFound
 

UUID             Volume           SVM             Date            LastSnapshot   
----             ------           ---             ----            ------------   
uuid-0           Name-0           SVM-0           date-0          snap-0
UUID             Volume           SVM             Date            LastSnapshot   
----             ------           ---             ----            ------------   
                                                                                 
                                                                                 
uuid-0           Name-0           SVM-0           date-0          snap-0         
uuid-1           Name-1           SVM-1           date-1          snap-1         
uuid-2           Name-2           SVM-2           date-2          snap-2
因此,我找到了一个“解决方案”,我使用下一个代码,这是可行的,但它不干净(最糟糕的是idk为什么它有效):

输出:

Method invocation failed because [System.Management.Automation.PSObject] does 
not contain a method named 'op_Addition'.
At line:14 char:5
+     $json += (ConvertFrom-Json -InputObject $blockvalue)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], Runtime 
   Exception
    + FullyQualifiedErrorId : MethodNotFound
 
Method invocation failed because [System.Management.Automation.PSObject] does 
not contain a method named 'op_Addition'.
At line:14 char:5
+     $json += (ConvertFrom-Json -InputObject $blockvalue)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], Runtime 
   Exception
    + FullyQualifiedErrorId : MethodNotFound
 

UUID             Volume           SVM             Date            LastSnapshot   
----             ------           ---             ----            ------------   
uuid-0           Name-0           SVM-0           date-0          snap-0
UUID             Volume           SVM             Date            LastSnapshot   
----             ------           ---             ----            ------------   
                                                                                 
                                                                                 
uuid-0           Name-0           SVM-0           date-0          snap-0         
uuid-1           Name-1           SVM-1           date-1          snap-1         
uuid-2           Name-2           SVM-2           date-2          snap-2
看看我期望什么:

UUID             Volume           SVM             Date            LastSnapshot   
----             ------           ---             ----            ------------   
uuid-0           Name-0           SVM-0           date-0          snap-0         
uuid-1           Name-1           SVM-1           date-1          snap-1         
uuid-2           Name-2           SVM-2           date-2          snap-2
我相信这很容易解决,但我没有天赋的PS


感谢advance提供的帮助:)

除了您正在使用的脚本的复杂性之外,只需声明一个数组,以便可以向其中添加项目:

$json2 = @()

foreach ($i in 0..2) {
    $blockvalue = @"
        { "UUID" : "uuid-$($i)",
            "Details" : [ { "Name" : "Name-$($i)" }, { "SVM" : "SVM-$($i) " }, { "LastSnapshot" : "snap-$($i)" }, { "Date" : "date-$($i) " } ] }
"@
    $json2 += (ConvertFrom-Json -InputObject $blockvalue)
}

$json2 | 
Select-Object UUID,
    @{ Name = "Volume";       Expression = { $_.Details | Select-Object -Expand Name         } },
    @{ Name = "SVM";          Expression = { $_.Details | Select-Object -Expand SVM          } },
    @{ Name = "Date";         Expression = { $_.Details | Select-Object -Expand Date         } },
    @{ Name = "LastSnapshot"; Expression = { $_.Details | Select-Object -Expand LastSnapshot } } |
Format-Table

使用
+=
附加数组通常是一种不好的做法。这种方法会导致创建一个新数组。原始操作数和右操作数的内容将复制到新数组中。对于小型作业来说,这不是什么大问题,但对于较大的数据集,这会导致性能指数级下降

对于快速POC或控制台类型以外的任何工作,我建议您避免在阵列上使用
+=
。最常见且通常最快的方法是简单地允许PowerShell为您累积输出。调整为:

我想建议多加一点语法糖;通常,您不需要在平面字符串上重复调用
Select Object-ExpandProperty…
。这段代码看起来更像

$json2 | 
Select-Object UUID,
    @{ Name = "Volume";       Expression = { $_.Details.Name         } },
    @{ Name = "SVM";          Expression = { $_.Details.SVM          } },
    @{ Name = "Date";         Expression = { $_.Details.Date         } },
    @{ Name = "LastSnapshot"; Expression = { $_.Details.LastSnapshot } } | 
Format-Table
然而,这产生了不寻常的结果。像上面那样展开属性会产生像Name-0、Null、Null、Null这样的数组。我追溯到JSON文本/结构。我不确定这是否是您的意图,但结果对象的结构如下:

@{UUID=uuid-0; Details=System.Object[]}
|- UUID = uuid-0
|  |- Length = 6
|- Details
| |- Details[0] = @{Name=Name-0}
| |  |- Name = Name-0
| |- Details[1] = @{SVM=SVM-1}
| |  |- SVM = SVM-1
| |- Details[2] = @{LastSnapShot=LastSnapShot-2}
| |  |- LastSnapShot = LastSnapShot-2
| |- Details[3] = @{Date=Date-3}
|    |- Date = Date-3
Details属性是一个对象数组,包含一系列多个对象,每个对象都有一个单独的属性,分别是Name、SVM等。。。我认为其目的可能是将细节作为一个对象,并将名称、SVM、LastSnapShot和日期作为属性。如果这是正确的,JSON创建可能更像下面这样,只有一组外部的花括号

$json2 = 
ForEach( $i in 0..2 ) {
@"
{ "UUID" : "uuid-$($i)",
    "Details" : [ { "Name" : "Name-$($i)", "SVM" : "SVM-$($i) ", "LastSnapshot" : "snap-$($i)", "Date" : "date-$($i) " } ] }
"@ | ConvertFrom-Json     
}

$json2 | 
Select-Object UUID,
    @{ Name = "Volume";       Expression = { $_.Details.Name         } },
    @{ Name = "SVM";          Expression = { $_.Details.SVM          } },
    @{ Name = "Date";         Expression = { $_.Details.Date         } },
    @{ Name = "LastSnapshot"; Expression = { $_.Details.LastSnapshot } } | 
Format-Table

在这种情况下,可以使用更简洁、可能更快的属性展开语法。

很有效,谢谢!我想我可以说得更简单一些,但就像我说的,我不是天才,这种解释需要时间,但非常有用。谢谢你的精心设计!