1

I'm working on a PowerShell client to a NoSQL-backed database. Not all of the documents in the table I query have the exact same set of properties. When using ConvertFrom-Json to serialize this payload the first JSON array item dictates the properties available to all other objects in the JSON payload.

Example:

@"
[
    {
        "thing1":  "bob",
        "thing2":  "mary"
    },
    {
        "thing1":  "bob",
        "thing2":  "mary",
        "thing3":  "tom"
    }
]
"@ | ConvertFrom-Json

thing1 thing2
------ ------
bob    mary
bob    mary
@"
[
    {
        "thing1":  "bob",
        "thing2":  "mary",
        "thing3":  "tom"
    },
    {
        "thing1":  "bob",
        "thing2":  "mary"
    }
]
"@ | ConvertFrom-Json

thing1 thing2 thing3
------ ------ ------
bob    mary   tom
bob    mary

Is this expected behavior? Is there a way around this other than attempting to parse the raw JSON on my own?

I'm currently using PowerShell 5.1:

$PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.18362.1801
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18362.1801
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
  • 1
    The property `thing3` for the element 1 (index starting from 0) will be there if that's what you're wondering. Even tho you're not seeing it on the console. – Santiago Squarzon Dec 15 '21 at 23:53
  • You can try storing the object first and then `$json.foreach({ $_ | Out-Host })` – Santiago Squarzon Dec 15 '21 at 23:56
  • You're absolutely correct Santiago, thanks for the quick reply. Selecting from the object array with `| select *` does nothing, but I can access the hidden property as you describe. – Chris Barton Dec 16 '21 at 00:08
  • Note that other cmdlets may suffer from this too, i.e.: `ConvertTo-Csv` and `Export-Csv`, if you were to export the first `object[]` as is you would be losing the 3rd column unless you sort it by the object having the most number of properties => `| Sort-Object { $_.PSObject.Properties.Count } -Descending | ConvertTo-Csv` try to convert with and without sorting :) – Santiago Squarzon Dec 16 '21 at 01:19
  • When `Format-Table` formatting is applied, which happens implicitly if an object has 4 or fewer properties, the _first_ object in a collection locks in all display columns based on its properties. If subsequent objects have _different properties_, only those they share with the first one are displayed; if a given object shares none, a blank line is displayed. This is only a _display problem_, as you can verify by piping the objects to `... | Format-List`. See [the linked duplicate](https://stackoverflow.com/a/69201252/45375) for more information. – mklement0 Dec 16 '21 at 03:12

1 Answers1

0

This is not an issue with ConvertFrom-Json. This is related to Write-Output missing columns. The reason is that PowerShell formats output as a table by default and uses the first row to format all rows. Just observe how these two objects are displayed.

[PSCustomObject]@{
    a=1;
} 
[PSCustomObject]@{
    a=2;b=3;
}

Try formatting output as list not a table to see that ConvertFrom-Json does not lose columns.

$json | ConvertFrom-Json|Format-List
Igor N.
  • 394
  • 2
  • 3