arraysjsonpowershellobjectpowershell-5.1

ConvertTo-Json ignores array in the inner object


I have an object I need to extend. The issue is after converting to JSON the inner array object is always empty. I don't understand where's my fail :(

$settings = @{}

# create the nested object
$settings | Add-Member -Type NoteProperty -Name nested_obj -Value @{}

# extend the nested object with an array property
$settings.nested_obj | Add-Member -Type NoteProperty -Name nested_property -Value @( "1", "2" )

# {"nested_property":["1","2"]}
Write-Host ( $settings.nested_obj | ConvertTo-Json -Compress -Depth 100 )

# {"nested_obj":{}} - the nested object is unexpectedly empty
Write-Host ( $settings | ConvertTo-Json -Compress -Depth 100 )

Thanks


Solution

  • ConvertTo-Json sees the object stored in $settings is a hashtable, and so rather than serializing properties, it starts serializing dictionary entries - of which you have none.

    Either attach the nested_obj and nested_property values as dictionary entries:

    # create root hashtable/dictionary
    $settings = @{}
    
    # create the nested hashtable
    $settings['nested_obj'] = @{}
    
    # add an entry to the nested hashtable
    $settings['nested_obj']['nested_property'] = @( "1", "2" )
    
    # {"nested_obj":{"nested_property":["1","2"]}}
    Write-Host ( $settings | ConvertTo-Json -Compress -Depth 100 )
    

    ... or, use actual (non-dictionary) objects

    # create object hierarchy
    $settings = [PSCustomObject]@{
      nested_obj = [PSCustomObject]@{
        nested_property = @( "1", "2" )
      }
    }
    
    # {"nested_obj":{"nested_property":["1","2"]}}
    Write-Host ( $settings | ConvertTo-Json -Compress -Depth 100 )
    

    The PowerShell 2.0-equivalent, using Add-Member, would be fairly similar to your initial attempt, with the difference that we replace @{} with New-Object psobject:

    $settings = New-Object psobject
    $settings | Add-Member -Type NoteProperty -Name nested_obj -Value (New-Object psobject)
    $settings.nested_obj | Add-Member -Type NoteProperty -Name nested_property -Value @( "1", "2" )
    
    # {"nested_obj":{"nested_property":["1","2"]}}
    Write-Host ( $settings | ConvertTo-Json -Compress -Depth 100 )