Powershell ConvertFrom-Json omitting Depth > 1

5.2k views Asked by At

Given this JSON

{"name":"//iam.googleapis.com/projects/aw-b9a-8231-4086-a297-ca0/serviceAccounts/1081069135974252","asset_type":"iam.googleapis.com/ServiceAccount","resource":{"version":"v1","discovery_document_uri":"https://iam.googleapis.com/$discovery/rest","discovery_name":"ServiceAccount","parent":"//cloudresourcemanager.googleapis.com/projects/1090951556423","data":{"email":"[email protected]","name":"projects/aw-d1eb6b9a-8231-4086-a297-ca0/serviceAccounts/[email protected]","oauth2ClientId":"108102635374252","projectId":"aw-d1eb6b9a-8231-4086-a297-ca0","uniqueId":"108108526913531974252"}},"ancestors":["projects/1090951556423","folders/940897400840","folders/140924730741","organizations/437515948226"],"update_time":"2021-02-08T18:23:18Z"}

I'm trying to use the following snippet from Windows command window,

powershell -nologo -executionpolicy bypass "& {foreach($line in Get-Content temp.txt) {ConvertFrom-Json -InputObject $line}}" > temp2.txt

To get the retrieved keys and values into a file (temp2.txt). However, ConvertFrom-Json only gets the first hierarchic level of the JSON, now down in the data array. I have tried -Depth 3 but get this error:

At line:1 char:81
+ ... ontent temp.txt) {ConvertFrom-Json  -InputObject $line -Depth 4 -Comp ...
+                                                            ~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [ConvertFrom-Json], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.ConvertFromJsonCommand```

1

There are 1 answers

2
mklement0 On BEST ANSWER

As Jeroen Mostert points out in a comment, only in PowerShell (Core) v6.2+ does ConvertFrom-Json have a -Depth parameter. However, even if it were available to you, it would neither be needed nor would it help, because ConvertFrom-Json correctly parses JSON with a nesting depth up to 1024 levels by default.

  • In other words: ConvertFrom-Json -Depth $someDepth is only needed in the unlikely event that your JSON has more than 1024 levels or if you want to ensure that input JSON does not exceed a given nesting depth (because exceeding it results in an error - unlike how -Depth works with the complementary cmdlet, ConvertTo-Json - see this post).

Your problem stems from the fact that >, PowerShell's redirection operator is in effect an alias of Out-File, which, when given complex objects as input, saves them using the same for-display representation you would see in the console - and with a deeply nested input object such as yours the resulting interpretation can be unhelpful (since your input object has more than 4 top-level properties, it is implicitly formatted with Format-List).

  • Note: You're actually using cmd.exe's > operator, but the above still applies, because the same kind of formatting is also applied when PowerShell outputs to an outside caller's stdout.

So the question for you to decide is:

  • What representation are you looking for to be saved in file temp2.txt?

  • Are you looking for a for-display representation - for the human observer - or a format suitable for later programmatic processing?

If you're primarily looking to pretty-print the input JSON, you can use a ConvertFrom-Json / ConvertTo-Json round-trip operation, whose output will be pretty-printed by default:

powershell -executionpolicy bypass -c "ConvertFrom-Json (Get-Content -Raw temp.txt) | ConvertTo-Json" > temp2.txt

Note:

  • As hinted at above, with ConvertTo-Json, i.e. the re-conversion to JSON, -Depth (available also in Windows PowerShell) is much more likely to be required (though not with your particular input object), because the default depth is only 2, and exceeding it results in quiet truncation (up to PowerShell 7.0; since v7.1, at least a warning is issued) - again, see this post.

  • I've streamlined incidental aspects of your call to powershell.exe, the Windows PowerShell CLI call - for a comprehensive overview of the CLI in both PowerShell editions, see this answer.

  • You may run into character-encoding issues with non-ASCII characters, given that cmd.exe uses the system's active OEM code page. Saving to a file from inside the PowerShell command can give you control over the desired encoding.