我有一个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
它什么也没给我
有人可以帮忙吗?
答案 0 :(得分:0)
如果保留数据不变,则可以将输出字符串作为脚本调用。这将产生一个具有可引用属性的哈希表。
$appVersion = $supportedVersions.value |
Where-Object { $_.ringFriendlyName -eq "Preview" } |
Select-Object -ExpandProperty "applicationVersion") | Invoke-Expression
$appVersion.Major
15
正如mclayton所指出的那样,这将不是首选方法。 Invoke-Expression
通常被认为是“不良”或“邪恶”的,因为恶意代码很容易在不知不觉中被执行。您必须信任提供数据的来源。
答案 1 :(得分:0)
您的JSON数据中的字段applicationVersion
的值是一个字符串。从外观上看,JSON是通过ConvertTo-Json
创建的,没有指定转换深度。默认情况下,ConvertTo-Json
将层次结构第二级以下的所有子结构转换为字符串。
解决您问题的最佳方法是通过向-Depth
调用中添加值> 2的参数ConvertTo-Json
来修复JSON导出,例如
... | ConvertTo-Json -Depth 10 | ...
如果无法执行此操作,则需要从字符串中解析出所需的信息,例如带有正则表达式:
$appVersion |
Select-String '(?<=major=)\d+' |
Select-Object -Expand Matches |
Select-Object -Expand Value
涉及脚本块的更具创意的方法可能看起来像这样:
$appVersion | ForEach-Object {
(& ([Scriptblock]::Create($_))).major
}
但是请注意,我实际上不建议使用后一种方法。
答案 2 :(得分:0)
对于您的示例来说,这可能是多余的,但是要安全将任意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