PowerShell: 通过字段值检索 JSON 对象

考虑下面这种格式的 JSON:

"Stuffs": [
{
"Name": "Darts",
"Type": "Fun Stuff"
},
{
"Name": "Clean Toilet",
"Type": "Boring Stuff"
}
]

在 PowerShell 3中,我们可以获得一个 Stuff 列表:

$JSON = Get-Content $jsonConfigFile | Out-String | ConvertFrom-Json

假设我们不知道列表的确切内容,包括对象的顺序,那么如何检索 Name 字段具有特定值的对象?

蛮力,我们可以重复这个列表:

foreach( $Stuff in $JSON.Stuffs ) {

但我希望存在一种更直接的机制(类似于 C # 中的 Lync 或 Lambda 表达式)。

236596 次浏览
$json = @"
{
"Stuffs":
[
{
"Name": "Darts",
"Type": "Fun Stuff"
},


{
"Name": "Clean Toilet",
"Type": "Boring Stuff"
}
]
}
"@


$x = $json | ConvertFrom-Json


$x.Stuffs[0] # access to Darts
$x.Stuffs[1] # access to Clean Toilet
$darts = $x.Stuffs | where { $_.Name -eq "Darts" } #Darts

I just asked the same question here: https://stackoverflow.com/a/23062370/3532136 It has a good solution. I hope it helps ^^. In resume, you can use this:

The Json file in my case was called jsonfile.json:

{
"CARD_MODEL_TITLE": "OWNER'S MANUAL",
"CARD_MODEL_SUBTITLE": "Configure your download",
"CARD_MODEL_SELECT": "Select Model",
"CARD_LANG_TITLE": "Select Language",
"CARD_LANG_DEVICE_LANG": "Your device",
"CARD_YEAR_TITLE": "Select Model Year",
"CARD_YEAR_LATEST": "(Latest)",
"STEPS_MODEL": "Model",
"STEPS_LANGUAGE": "Language",
"STEPS_YEAR": "Model Year",
"BUTTON_BACK": "Back",
"BUTTON_NEXT": "Next",
"BUTTON_CLOSE": "Close"
}

Code:

$json = (Get-Content "jsonfile.json" -Raw) | ConvertFrom-Json


$json.psobject.properties.name

Output:

CARD_MODEL_TITLE
CARD_MODEL_SUBTITLE
CARD_MODEL_SELECT
CARD_LANG_TITLE
CARD_LANG_DEVICE_LANG
CARD_YEAR_TITLE
CARD_YEAR_LATEST
STEPS_MODEL
STEPS_LANGUAGE
STEPS_YEAR
BUTTON_BACK
BUTTON_NEXT
BUTTON_CLOSE

Thanks to mjolinor.

David Brabant's answer led me to what I needed, with this addition:

x.Stuffs | where { $_.Name -eq "Darts" } | Select -ExpandProperty Type

This is my json data:

[
{
"name":"Test",
"value":"TestValue"
},
{
"name":"Test",
"value":"TestValue"
}
]

Powershell script:

$data = Get-Content "Path to json file" | Out-String | ConvertFrom-Json


foreach ($line in $data) {
$line.name
}

Hows about this:

$json=Get-Content -Raw -Path 'my.json' | Out-String | ConvertFrom-Json
$foo="TheVariableYourUsingToSelectSomething"
$json.SomePathYouKnow.psobject.properties.Where({$_.name -eq $foo}).value

which would select from json structured

{"SomePathYouKnow":{"TheVariableYourUsingToSelectSomething": "Tada!"}

This is based on this accessing values in powershell SO question . Isn't powershell fabulous!

In regards to PowerShell 5.1 ...

Operating off the assumption that we have a file named jsonConfigFile.json with the following content from your post:

{
"Stuffs": [
{
"Name": "Darts",
"Type": "Fun Stuff"
},
{
"Name": "Clean Toilet",
"Type": "Boring Stuff"
}
]
}

This will create an ordered hashtable from a JSON file to help make retrieval easier:

$json = [ordered]@{}


(Get-Content "jsonConfigFile.json" -Raw | ConvertFrom-Json).PSObject.Properties |
ForEach-Object { $json[$_.Name] = $_.Value }

$json.Stuffs will list a nice hashtable, but it gets a little more complicated from here. Say you want the Type key's value associated with the Clean Toilet key, you would retrieve it like this:

$json.Stuffs.Where({$_.Name -eq "Clean Toilet"}).Type

It's a pain in the ass, but if your goal is to use JSON on a barebones Windows 10 installation, this is the best way to do it as far as I've found.