簡體   English   中英

如何從Powershell中的JSON值獲取值

[英]How to get value from json value in powershell

我有一個json文件

{
"value":  [
              {
                  "applicationVersion":  "@{major=14; minor=5; build=35970; revision=0; majorRevision=0; minorRevision=0}",
                  "ringName":  "PROD",
                  "ringFriendlyName":  "Production"
              },
              {
                  "applicationVersion":  "@{major=15; minor=0; build=35903; revision=0; majorRevision=0; minorRevision=0}",
                  "ringName":  "PREVIEW",
                  "ringFriendlyName":  "Preview"
              }
          ]
}

我想從ringName = Preview獲取主要,次要,內部版本和修訂版值。

我試過了

$supportedVersions = $myJson | ConvertFrom-Json
$appVersion = $supportedVersions.value | where { $_.ringFriendlyName -eq "Preview" } | Select -ExpandProperty "applicationVersion" 

這回來了我

@{major=15; minor=0; build=35903; revision=0; majorRevision=0; minorRevision=0}

但是當我嘗試

    $major = $appVersion | select major

它什么也沒回報

在此處輸入圖片說明

有人可以幫忙嗎?

如果按原樣保留數據,則可以將輸出字符串作為腳本調用。 這將產生一個具有可引用屬性的哈希表。

$appVersion = $supportedVersions.value |
    Where-Object { $_.ringFriendlyName -eq "Preview" } |
        Select-Object -ExpandProperty "applicationVersion") | Invoke-Expression

$appVersion.Major
15

正如麥克萊頓指出的那樣,這將不是首選方法。 Invoke-Expression通常被認為是“不良”或“邪惡”的,因為惡意代碼很容易在不知不覺中被執行。 您必須信任提供數據的來源。

JSON數據中的applicationVersion字段的值是一個字符串。 從外觀ConvertTo-Json ,JSON是通過ConvertTo-Json創建的,沒有指定轉換深度。 默認情況下, ConvertTo-Json會將層次結構第二級以下的所有子結構都處理成字符串。

解決您的問題的最佳方法是通過在ConvertTo-Json調用中添加值大於2的參數-Depth來修復JSON導出,例如

... | ConvertTo-Json -Depth 10 | ...

如果不能這樣做,則需要從字符串中解析出所需的信息,例如使用正則表達式:

$appVersion |
    Select-String '(?<=major=)\d+' |
    Select-Object -Expand Matches |
    Select-Object -Expand Value

涉及腳本塊的更具創意的方法可能如下所示:

$appVersion | ForEach-Object {
    (& ([Scriptblock]::Create($_))).major
}

但是請注意,我實際上不建議使用后一種方法。

對於您的示例來說,這可能是過分的,但是要安全地將任意PowerShell表達式轉換為值,可以使用內置的PowerShell解析器。 下面的代碼適用於哈希表...

function ConvertTo-HashTable
{
    param( [string] $PsCode )
    $tokens = $null;
    $errors = $null;
    $scriptBlockAst = [System.Management.Automation.Language.Parser]::ParseInput($PsCode, [ref] $tokens, [ref] $errors);
    if( $errors.Length -gt 0 )
    {
        throw "Invalid powershell script - errors are:`r`n$errors";
    }
    $hashtableAst = $scriptBlockAst.EndBlock.Statements[0].PipelineElements[0].Expression;
    if( ($null -eq $hashtableAst) -or
        -not ($hashtableAst -is [System.Management.Automation.Language.HashTableAst]) )
    {
        throw "couldn't find a hashtable in the script";
    }
    return $hashtableAst.SafeGetValue();
}

例:

PS> ConvertTo-Hashtable "@{`"major`" = 15}"

Name                           Value
----                           -----
major                          15

請注意,如果字符串中包含任何表達式,它將引發異常,從而保護您免受PowerShell注入攻擊:

PS> ConvertTo-Hashtable "@{`"major`" = 1 + 1}"
Exception calling "SafeGetValue" with "0" argument(s): "Cannot generate a Windows PowerShell object for a ScriptBlock
evaluating dynamic expressions. Dynamic expression: @{"major" = 1 + 1}."
At line:17 char:12
+     return $hashtableAst.SafeGetValue();
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : InvalidOperationException
PS> ConvertTo-Hashtable "@{`"major`" = (Format-Volume -DriveLetter X)}"
Exception calling "SafeGetValue" with "0" argument(s): "Cannot generate a Windows PowerShell object for a ScriptBlock
evaluating dynamic expressions. Dynamic expression: @{"major" = (Format-Volume -DriveLetter X)}."
At line:17 char:12
+     return $hashtableAst.SafeGetValue();
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : InvalidOperationException

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM