Answered by:
How to Output Entire Content of JSON Nested Hash Table in PoweShell

Question
-
How can I output the entire contents of a nested JSON hash table to a PS object in one line?
$json = @" { "outer": "value1", "outerArray": [ "value2", "value3" ], "outerHash": { "inner": "value4", "innerArray": [ "value5", "value6" ], "innerHash": { "innermost1": "value7", "innermost2": "value8", "innermost3": "value9" } } } "@
Current behavior: PowerShell by default only displays one level down into the data (you can see here that "innerArray" and "innerHash" are both truncated since they are not in the first level of the data structure
$json | ConvertFrom-Json outer outerArray outerHash ----- ---------- --------- value1 {value2, value3} @{inner=value4; innerArray=System.Object[]; innerHash=}
Desired behavior: Recursively expand and display all hash/array content (notice that "innerArray" and "innerHash" are both expanded)
$json | ConvertFrom-Json outer outerArray outerHash ----- ---------- --------- value1 {value2, value3} @{inner=value4; innerArray=@(value5, value6); innerHash=@{innermost1=value7; innermost2=value8; innermost3=value9}}
I understand this entails some sort of custom parsing / formatting but not sure how the code should look. Sample code appreciated.
- Edited by atscripter Wednesday, February 6, 2019 5:54 PM clarify question
Wednesday, February 6, 2019 4:25 PM
Answers
-
The solution to this was graciously provided by iRon on another forum. This entailed using the custom ConvertTo-Expression function to iterate through the JSON block and output a PS custom object for each nested hash/array.
Command:
$Properties = @{} ($Json | ConvertFrom-Json).PSObject.Properties | ForEach-Object {$Properties.($_.Name) = $_.Value | ConvertTo-Expression -Expand -1} [PSCustomObject]$Properties
Output:
outer outerArray outerHash ----- ---------- --------- 'value1' 'value2','value3' [PSCustomObject]@{'inner'='value4';'innerArray'='value5','value6';'innerHash'=[PSCustomObject]@{'innermost1'='value7';'innermost2'='value8';'innermost3'='value9'}}
Thanks again to all who contributed.
- Marked as answer by atscripter Tuesday, February 12, 2019 4:08 PM
- Edited by atscripter Tuesday, February 12, 2019 4:10 PM
Tuesday, February 12, 2019 4:08 PM
All replies
-
Does answer #8 in this post help?
I ran the code below and got this as a result:
Name Value ---- ----- outer value1 outerArray {value2, value3} outerHash {innerArray, innerHash, inner}
function ConvertPSObjectToHashtable { param ( [Parameter(ValueFromPipeline)] $InputObject ) process { if ($null -eq $InputObject) { return $null } if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) { $collection = @( foreach ($object in $InputObject) { ConvertPSObjectToHashtable $object } ) Write-Output -NoEnumerate $collection } elseif ($InputObject -is [psobject]) { $hash = @{} foreach ($property in $InputObject.PSObject.Properties) { $hash[$property.Name] = ConvertPSObjectToHashtable $property.Value } $hash } else { $InputObject } } } $json = @" { "outer": "value1", "outerArray": [ "value2", "value3" ], "outerHash": { "inner": "value4", "innerArray": [ "value5", "value6" ], "innerHash": { "innermost1": "value7", "innermost2": "value8", "innermost3": "value9" } } } "@ $j = $json | ConvertFrom-Json $x = $j | ConvertPSObjectToHashtable
--- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)
Wednesday, February 6, 2019 4:44 PM -
Thanks for pitching in Rich! Unfortunately that provides the same truncated output. I am looking for an expanded output as illustrated under "desired effect" above.Wednesday, February 6, 2019 5:03 PM
-
The objects are created correctly:
PS D:\scripts> $json = @" >> { >> "outer": "value1", >> "outerArray": [ >> "value2", >> "value3" >> ], >> "outerHash": { >> "inner": "value4", >> "innerArray": [ >> "value5", >> "value6" >> ], >> "innerHash": { >> "innermost1": "value7", >> "innermost2": "value8", >> "innermost3": "value9" >> } >> } >> } >> "@ | ConvertFrom-Json PS D:\scripts> $json outer outerArray outerHash ----- ---------- --------- value1 {value2, value3} @{inner=value4; innerArray=System.Object[]; innerHash=} PS D:\scripts> $json.OuterArray value2 value3 PS D:\scripts> $json.OuterHash inner innerArray innerHash ----- ---------- --------- value4 {value5, value6} @{innermost1=value7; innermost2=value8; innermost3=value9} PS D:\scripts> $json.OuterHash.innerHash innermost1 innermost2 innermost3 ---------- ---------- ---------- value7 value8 value9 PS D:\scripts>
\_(ツ)_/
Wednesday, February 6, 2019 5:17 PM -
jrv - The objects are indeed parsed correctly but my request is specific to output formatting. PowerShell's default behavior is to only display one level down the hash (notice how you had to append .innerHash to display inner content). I want to be able to recursively expand and output all inner hash/array contents without appending .innerContent for each sub-level.Wednesday, February 6, 2019 5:29 PM
-
You can use select expand to display the nested contents, but not sure how/if you can leverage it to get your desired results.
$json | Select-Object -ExpandProperty outerhash
Wednesday, February 6, 2019 5:42 PM -
jrv - The objects are indeed parsed correctly but my request is specific to output formatting. PowerShell's default behavior is to only display one level down the hash (notice how you had to append .innerHash to display inner content). I want to be able to recursively expand and output all inner hash/array contents without appending .innerContent for each sub-level.
That is how PowerShell works. If you want different output you will need to write a script that does what you need.
\_(ツ)_/
Wednesday, February 6, 2019 5:44 PM -
You can use select expand to display the nested contents, but not sure how/if you can leverage it to get your desired results.
$json | Select-Object -ExpandProperty outerhash
Yes, the question here is how to recursively expand the contents without having to specify it for each child object.Wednesday, February 6, 2019 5:56 PM -
jrv - The objects are indeed parsed correctly but my request is specific to output formatting. PowerShell's default behavior is to only display one level down the hash (notice how you had to append .innerHash to display inner content). I want to be able to recursively expand and output all inner hash/array contents without appending .innerContent for each sub-level.
That is how PowerShell works. If you want different output you will need to write a script that does what you need.
\_(ツ)_/
Wednesday, February 6, 2019 6:00 PM -
You will need to write a recursive function that detects imbedded objects and decide how to output them (format). We will not write that for you. Start writing it and ask specific questions as you progress.
\_(ツ)_/
Wednesday, February 6, 2019 6:02 PM -
The solution to this was graciously provided by iRon on another forum. This entailed using the custom ConvertTo-Expression function to iterate through the JSON block and output a PS custom object for each nested hash/array.
Command:
$Properties = @{} ($Json | ConvertFrom-Json).PSObject.Properties | ForEach-Object {$Properties.($_.Name) = $_.Value | ConvertTo-Expression -Expand -1} [PSCustomObject]$Properties
Output:
outer outerArray outerHash ----- ---------- --------- 'value1' 'value2','value3' [PSCustomObject]@{'inner'='value4';'innerArray'='value5','value6';'innerHash'=[PSCustomObject]@{'innermost1'='value7';'innermost2'='value8';'innermost3'='value9'}}
Thanks again to all who contributed.
- Marked as answer by atscripter Tuesday, February 12, 2019 4:08 PM
- Edited by atscripter Tuesday, February 12, 2019 4:10 PM
Tuesday, February 12, 2019 4:08 PM