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-Json before sending data to an API or saving structured output to a file.
  • Use ConvertFrom-Json after 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 -Depth high 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
$json

Output

{"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 5

If 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

  • -Compress removes whitespace. Use it for logs, API bodies, and places where readability is not important.
  • -AsArray wraps even a single object in a JSON array, which is useful when an API schema always expects an array.
  • -EnumsAsStrings serializes enum names instead of numeric values, which is often easier to read and safer for external integrations.
  • -EscapeHandling lets 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 -AsArray

Output

[
  {
    "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
$data

Preserve 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.

  • Default uses the cmdlet's normal date parsing behavior.
  • Utc or Local is useful when you want an explicit timezone interpretation.
  • Offset is helpful when preserving offset information matters.
  • String keeps 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().FullName

Common Pitfalls and Practical Fixes

  • Nested JSON is incomplete: Increase ConvertTo-Json -Depth.
  • Reading from a file behaves strangely: Prefer Get-Content -Raw so you pass one JSON string into ConvertFrom-Json.
  • Keys collide or object access is awkward: Use -AsHashtable.
  • A one-element array comes back as a scalar: Use -NoEnumerate on 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/catch and 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.json

Summary

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