Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool
PowerShell's ConvertTo-Json and ConvertFrom-Json Commands
ConvertTo-Json turns PowerShell objects into JSON text. ConvertFrom-Json does the reverse and turns JSON text into PowerShell objects you can query and update. If you work with REST APIs, configuration files, or command output that needs to cross tool boundaries, these are the two JSON cmdlets you use constantly.
The most common mistakes are also the simplest ones: forgetting that ConvertTo-Json defaults to -Depth 2, and reading a JSON file with Get-Content but not using -Raw. Fix those two issues and most day-to-day PowerShell JSON problems disappear.
Quick Mental Model
- Use
ConvertTo-Jsonbefore sending data to an API or saving structured output to a file. - Use
ConvertFrom-Jsonafter reading JSON from a file, an API response, or a string variable. - For files, the safest pattern is
Get-Content -Raw path.json | ConvertFrom-Json. - For nested objects, explicitly set
ConvertTo-Json -Depthhigh enough for your real object graph.
ConvertTo-Json: Sending PowerShell Data Out
ConvertTo-Json serializes the data portion of PowerShell objects into JSON text. It is ideal for REST request bodies, logs, exports, and config files. It is not a perfect round-trip serializer for every .NET type, so treat it as a data export step rather than a way to preserve methods or full runtime behavior.
Example: Build an API Request Body
$body = [PSCustomObject]@{
action = "deploy"
environment = "prod"
items = @(
[PSCustomObject]@{
sku = "A-100"
quantity = 2
}
)
}
$json = $body | ConvertTo-Json -Depth 4 -Compress
$jsonOutput
{"action":"deploy","environment":"prod","items":[{"sku":"A-100","quantity":2}]}The Parameter That Matters Most: -Depth
The default serialization depth is 2. That is fine for flat objects, but it is too shallow for most real payloads. If your JSON suddenly shows truncated nested objects, raise the depth deliberately instead of guessing.
$deployment = [PSCustomObject]@{
name = "frontend"
metadata = [PSCustomObject]@{
region = "us-east-1"
owner = [PSCustomObject]@{
team = "web"
onCall = "ops@example.com"
}
}
}
$deployment | ConvertTo-Json
$deployment | ConvertTo-Json -Depth 5If you see warnings or incomplete nested output, the depth is too low. Raise it to the minimum value that matches your real structure.
Other Useful ConvertTo-Json Switches
-Compressremoves whitespace. Use it for logs, API bodies, and places where readability is not important.-AsArraywraps even a single object in a JSON array, which is useful when an API schema always expects an array.-EnumsAsStringsserializes enum names instead of numeric values, which is often easier to read and safer for external integrations.-EscapeHandlinglets you control whether HTML-sensitive or non-ASCII characters are escaped.
Example: Force an Array for a Single Item
[PSCustomObject]@{
name = "Alice"
role = "admin"
} | ConvertTo-Json -AsArrayOutput
[
{
"name": "Alice",
"role": "admin"
}
]ConvertFrom-Json: Reading JSON Back Into PowerShell
ConvertFrom-Json turns JSON text into a PSCustomObject, an array, or a hashtable depending on how you call it. This is what you use when you want dot notation, filtering, updates, and normal PowerShell object handling on top of JSON data.
Example: Read a JSON File Reliably
$config = Get-Content -Path .\config.json -Raw | ConvertFrom-Json $config.database.server $config.features.betaMode
Get-Content without -Raw returns an array of lines, not one JSON string. -Raw is the safer default for JSON files.
When To Use -AsHashtable
Use -AsHashtable when dot notation is less important than preserving key behavior. This is especially helpful when JSON keys differ only by case, or when the JSON contains keys that are awkward for a PSCustomObject. In PowerShell 7.3 and later, the result is an ordered hashtable, so key order is preserved.
$json = '{
"key": "lowercase value",
"Key": "uppercase value",
"": "blank key"
}'
$data = $json | ConvertFrom-Json -AsHashtable
$dataPreserve Single-Item Arrays with -NoEnumerate
A JSON array with one item can quietly become a scalar when it flows through the pipeline. If you need to keep it as an array for a later round trip, use -NoEnumerate.
'[1]' | ConvertFrom-Json | ConvertTo-Json -Compress '[1]' | ConvertFrom-Json -NoEnumerate | ConvertTo-Json -Compress
Output
1 [1]
PowerShell 7.5: Control Date Parsing with -DateKind
PowerShell 7.5 adds -DateKind to ConvertFrom-Json. That matters if your JSON contains timestamps and you need predictable conversion behavior. Use it when the default date parsing is not explicit enough for your script.
Defaultuses the cmdlet's normal date parsing behavior.UtcorLocalis useful when you want an explicit timezone interpretation.Offsetis helpful when preserving offset information matters.Stringkeeps the original timestamp text instead of converting it to a date object.
$event = '{"generatedAt":"2026-03-10T18:45:00Z"}' |
ConvertFrom-Json -DateKind Utc
$event.generatedAt
$event.generatedAt.GetType().FullNameCommon Pitfalls and Practical Fixes
- Nested JSON is incomplete: Increase
ConvertTo-Json -Depth. - Reading from a file behaves strangely: Prefer
Get-Content -Rawso you pass one JSON string intoConvertFrom-Json. - Keys collide or object access is awkward: Use
-AsHashtable. - A one-element array comes back as a scalar: Use
-NoEnumerateon import. - Round-tripping is not identical: JSON preserves data, not PowerShell methods, script properties, or every original .NET type detail.
- Malformed JSON throws immediately: Wrap external input in
try/catchand validate it before depending on it.
A Good Workflow with a JSON Formatter
PowerShell is excellent at generating and consuming JSON, but it is not the best place to visually inspect a large payload. A useful workflow is to produce the JSON in PowerShell, then paste it into an offline JSON formatter to pretty-print it, validate the structure, and inspect deeply nested sections before sending it to another system.
Example: Update a Config File and Write It Back
$config = Get-Content -Path .\appsettings.json -Raw | ConvertFrom-Json
$config.logging.level = "Warning"
$config |
ConvertTo-Json -Depth 10 |
Set-Content -Path .\appsettings.jsonSummary
For most PowerShell JSON work, remember four rules: import files with Get-Content -Raw, increase ConvertTo-Json -Depth for nested objects, use -AsHashtable when key behavior matters, and use -NoEnumerate when array shape must survive a round trip. On PowerShell 7.5, add -DateKind when timestamp parsing needs to be explicit instead of implicit.
Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool