Port Igniter
Get Started

PowerShell Basics for JSON Operations

An easy to follow guide on how to use PowerShell for quick local data manipulation

May 23, 2026

PowerShell & JSON: A Practical Primer

JSON has become the universal language of data exchange — and PowerShell handles it surprisingly well. Whether you’re parsing API responses, transforming configuration files, or extracting subsets of records, PowerShell’s built-in “cmdlets” get the job done without having to rely on third-party tools. One of the biggest strong suits, in my opinion, of using an Object-Oriented shell scripting language like PowerShell, is the versatility to transform and query sets of data on the fly. A lot of opponents to PowerShell target this object-oriented design as bloated or uneccessary, but I disagree.

In PowerShell, an object is a structured piece of data that bundles together two things:

  • Properties — the data it holds (e.g., a file object has .Name, .Size, .LastWriteTime)
  • Methods — actions it can perform (e.g., a string object has .ToUpper(), .Replace())

This comes from .NET, which PowerShell is built on. Almost everything in PowerShell is an object — strings, numbers, files, processes, JSON records, command output — rather than plain text like in traditional shells such as BASH, ZSH etc.

The practical upside is that you can “dot” into properties directly instead of some complicated mechanism to parse and extract textual data yourself. here’s a quick example:

# Example of getting file properties
$file = Get-Item ".\data.json"
$file.Name          # "data.json"
$file.Length        # 4096  (bytes, as a number you can compare/sort)

In the context of this article, when you run ConvertFrom-Json, PowerShell turns your JSON into a PSCustomObject — an object whose properties map directly to your JSON keys. That’s why you can write $_.address.city to drill into nested fields, rather than doing any string parsing yourself.


Loading JSON

Loading JSON into a local shell variable is extremely easy. Most of the work I do, relies on quick iterations against a set of data to work out a more cohesive solution to parse and cherry-pick the data I need for the given problem.

Loading Data from a File

Use Get-Content to read the file and pipe it into ConvertFrom-Json:

$data = Get-Content -Path ".\users.json" -Raw | ConvertFrom-Json

The -Raw flag reads the entire file as a single string rather than line-by-line — this is essential for valid JSON parsing.

Loading Data from an API or Web Request

Invoke-RestMethod automatically deserializes JSON responses for you:

$response = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/users"
The result is already a PowerShell object — no ConvertFrom-Json invocation needed.

Inspecting the Structure

Once loaded, explore the object like any other:

$data | Get-Member          # Show properties and methods
$data | Select-Object -First 3  # Preview the first 3 records
$data.Count                 # Total number of items

Searching and Filtering

Probably one of the most powerful features of PowerShell, is the ability chain cmdlets together to both select and iterate over large sets of data. I often use PowerShell over a Python repl to map out data, since PowerShell lets you quickly iterate over list like structures, to get subvalues, much more intuitively. In larger, more complicated, JSON files that could change their structure based on the dataset, this becomes invaluable.

Simple Property Match

Use Where-Object to filter records:

# Find all users in a specific city
$data | Where-Object { $_.address.city -eq "Portland" }

# Find users whose name starts with "J"
$data | Where-Object { $_.name -like "J*" }

The $_ in the above script, could also be written as $PSItem and simply represents the current item being iterated over.

Numeric Comparisons

# Orders over $500
$orders | Where-Object { $_.total -gt 500 }

# Items with low stock
$inventory | Where-Object { $_.quantity -le 10 }

Multiple Conditions

$data | Where-Object { $_.status -eq "active" -and $_.role -eq "admin" }

Selecting and Reshaping Fields

Use Select-Object to pick only the fields you need:

$data | Select-Object name, email, @{Name="City"; Expression={$_.address.city}}

The @{Name=...; Expression={...}} syntax lets you rename or compute fields on the fly — handy for flattening nested structures.


Exporting Subsets

Most often, you will probably want to extract and save subsets of data you are inspecting. In these cases, it is easy to select, extract, and reshape / massage your data into a format that you can then hand off to an export function of some kind. This could be for automated reporting processes or any other one off scripts you are using to inspect target processes.

Export to CSV

Once you have a filtered, shaped result, Export-Csv writes it out cleanly:

$data |
    Where-Object { $_.status -eq "active" } |
    Select-Object id, name, email |
    Export-Csv -Path ".\active_users.csv" -NoTypeInformation

-NoTypeInformation suppresses the #TYPE header line that PowerShell adds by default — you almost always want this.

Export Back to JSON

To write a filtered subset back out as JSON:

$data |
    Where-Object { $_.role -eq "admin" } |
    ConvertTo-Json -Depth 5 |
    Out-File -FilePath ".\admins.json"

The -Depth parameter controls how many levels of nested objects are serialized. The default is 2, which silently truncates deeper structures — set it higher when working with complex JSON.

Export to a Table in the Console

For quick inspection without writing a file:

$data | Where-Object { $_.active -eq $true } | Format-Table -AutoSize

Modifying JSON Data

You can update properties in memory and re-export:

# Add a new field to every record
$data | ForEach-Object { $_ | Add-Member -NotePropertyName "exported_at" -NotePropertyValue (Get-Date -Format "o") -Force }

# Update a specific record
($data | Where-Object { $_.id -eq 42 }).status = "inactive"

# Save the modified data
$data | ConvertTo-Json -Depth 5 | Out-File ".\updated_data.json"

Putting It All Together

Here’s a complete workflow: load a JSON file, filter it, reshape it, and export two formats:

# 1. Load
$users = Get-Content ".\users.json" -Raw | ConvertFrom-Json

# 2. Filter and shape
$subset = $users |
    Where-Object { $_.active -eq $true -and $_.role -ne "guest" } |
    Select-Object id, name, email, role,
        @{Name="City"; Expression={$_.address.city}}

# 3. Export to CSV
$subset | Export-Csv ".\active_non_guests.csv" -NoTypeInformation

# 4. Export to JSON
$subset | ConvertTo-Json -Depth 3 | Out-File ".\active_non_guests.json"

Write-Host "Done. $($subset.Count) records exported."

Quick Reference

Below is quick reference of some of the concepts we explored together in this article.

Task Cmdlet
Load JSON from file Get-Content -Raw | ConvertFrom-Json
Load JSON from URL Invoke-RestMethod
Filter records Where-Object { $_.prop -eq "value" }
Pick fields / rename Select-Object with computed properties
Export to CSV Export-Csv -NoTypeInformation
Export to JSON ConvertTo-Json -Depth N | Out-File
Modify in-place ForEach-Object + Add-Member or direct assignment

Bottom Line

PowerShell’s pipeline model makes JSON workflows feel natural — each step flows cleanly into the next. Once you’re comfortable with ConvertFrom-Json, Where-Object, and Select-Object — you have everything you need to slice and reshape almost any JSON dataset.

Think we might be a good fit for your project?

Let's get the conversation started!

Top