Working with JSON
Prerequisites: Custom objects, Hash tables
ConvertFrom-Json turns JSON text into objects; ConvertTo-Json turns
objects into JSON.
$json = @'
{
"name": "web01",
"ports": [80, 443],
"owner": { "team": "platform", "email": "ops@example.com" }
}
'@
$config = $json | ConvertFrom-Json
$config.name
$config.ports -join ', '
$config.owner.team
web01
80, 443
platform
Nested objects and arrays become nested properties — navigate with dots.
Creating JSON
$report = [ordered]@{
generated = '2025-04-22'
servers = @(
@{ name = 'web01'; healthy = $true }
@{ name = 'db01'; healthy = $false }
)
}
$report | ConvertTo-Json
{
"generated": "2025-04-22",
"servers": [
{
"healthy": true,
"name": "web01"
},
{
"healthy": false,
"name": "db01"
}
]
}
The -Depth trap
ConvertTo-Json only goes 2 levels deep by default. Deeper data is
flattened to text, with a warning:
$deep = @{ a = @{ b = @{ c = @{ d = 'value' } } } }
$deep | ConvertTo-Json -Compress
$deep | ConvertTo-Json -Compress -Depth 10
WARNING: Resulting JSON is truncated as serialization has exceeded the set depth of 2.
{"a":{"b":{"c":"System.Collections.Hashtable"}}}
{"a":{"b":{"c":{"d":"value"}}}}
Always pass -Depth for nested data (the maximum is 100).
-Compress removes whitespace.
Files and editing
Set-Content settings.json '{ "theme": "light", "fontSize": 14 }'
$settings = Get-Content settings.json -Raw | ConvertFrom-Json
$settings.theme = 'dark'
$settings | Add-Member -NotePropertyName autosave -NotePropertyValue $true
$settings | ConvertTo-Json -Compress | Set-Content settings.json
Get-Content settings.json
{"theme":"dark","fontSize":14,"autosave":true}
Use -Raw when reading, so the whole file is parsed as one document.
ConvertFrom-Json -AsHashtable returns hash tables instead, useful when
keys aren't valid property names. Check or pretty-print JSON with the
JSON Formatter.