2

Given the two JSON examples

{
    "A": {
        "name": "noname",
        "key": "nokey"
    }

and then

{
    "B": {
        "property1": "value3",
        "country": "australia"
    }
}

Is it possible to create a Powershell script that could take either one of the JSON examples and loop through them without knowing any names/keys upfront? (Using Windows 2016)

Something similar to what is posted as an answer here How do I loop through or enumerate a JavaScript object?

var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};

for (var key in p) {
  if (p.hasOwnProperty(key)) {
    console.log(key + " -> " + p[key]);
  }
}

Not working

Did try this, but it works only for the first level

$json = @"
 {"A": {"property1": "value1", "property2": "value2"}, "B": {"property1": 
 "value3", "property2": "value4"}}
"@

$parsed = $json | ConvertFrom-Json

$parsed.PSObject.Properties | ForEach-Object {
    $next = $_
    $name = $_.Name 
    $value = $_.value
    echo "$name = $value"

    $next.PSObject.Properties | ForEach-Object {
        $name = $_.Name 
        $value = $_.value
        echo "Second level: $name = $value"
    } 
}
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
rhellem
  • 769
  • 1
  • 11
  • 26
  • ```$next.PSObject.Properties``` needs to be ```$next.Value.PSObject.Properties``` in your update. You want to get the child properties of the root **property value**, not root **property object**... – mclayton Nov 11 '19 at 20:42

1 Answers1

4

ConvertFrom-Json uses a nested structure of PSCustomObjects to represent the data - you can use $x.psobject.properties to get a collection of json property names and values for each item in the structure, and then you can loop over them however you want.

For example:

$x = ConvertFrom-Json "{ 'A': {'name': 'noname', 'key': 'nokey'} }"

foreach( $rootProperty in @($x.psobject.properties | where-object {$_.MemberType -eq "NoteProperty"}) )
{

    write-host "'$($rootProperty.Name)' = '$($rootProperty.Value)'"

    foreach( $childProperty in @($rootProperty.Value.psobject.properties | where-object {$_.MemberType -eq "NoteProperty"}) )
    {
        write-host "'$($childProperty.Name)' = '$($childProperty.Value)'"
    }

}

outputs the following:

'A' = '@{name=noname; key=nokey}'
'name' = 'noname'
'key' = 'nokey'

You could also walk the structure recursively to an arbitrary depth if you convert the above into a function that calls itself on nested PSCustomObjects, but I'm not sure if you need to be able to do that or just go 2 levels like in your example json documents.

mclayton
  • 8,025
  • 2
  • 21
  • 26
  • Had to post a follow up https://stackoverflow.com/questions/59097291/yet-another-loop-json-object-using-powershell – rhellem Nov 28 '19 at 23:58