Hashtables from ConvertFrom-json have different type from powershells built-in hashtables, how do I make them the same?
Here's a quick function to convert a PSObject back into a hashtable (with support for nested objects; intended for use with DSC ConfigurationData, but can be used wherever you need it).
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 } }}
The ConvertFrom-Json
cmdlet gives you a custom object so you have to access them using dot notation rather than as a subscript. Usually you would know what fields you expect in the JSON so this is actually more useful in general than getting a hash table. Rather than fighting the system by converting back to a hash table, I suggest you work with it.
You can use select
with wildcard property names to get at the properties:
PS D:\> $data = @"{ "root": { "key":"value", "key2":"value2", "another":42 }}"@ | ConvertFrom-JsonPS D:\> $data.root | select * | ft -AutoSizekey key2 another--- ---- -------value value2 42PS D:\> $data.root | select k* | ft -AutoSizekey key2 --- ---- value value2
and Get-Member
if you want to extract a list of property names that you can iterate over:
PS D:\> ($data.root | Get-Member -MemberType NoteProperty).Nameanotherkeykey2
Putting that into a loop gives code like this:
PS D:\> foreach ($k in ($data.root | Get-Member k* -MemberType NoteProperty).Name) { Write-Output "$k = $($data.root.$k)" }key = valuekey2 = value2
The example was for a relatively shallow source object (not nested objects in the properties).
Here's a version that will go 2 levels deep into the source object, and should work with your data:
$data = @{}foreach ($propL1 in $x.psobject.properties.name) { $data[$propL1] = @{} foreach ($propL2 in $x.$propL1.psobject.properties.name) { $data[$PropL1][$PropL2] = $x.$propL1.$propL2 } }$data.root.keyskey