This blog provides a simple example of using PowerShell to read and write JSON.
PowerShell and JSON – Objects, Arrays, Hashtables and Ordering
For the context of this post, think of an example JSON object being a “school”, a JSON property name being the school’s name, and an array being a list of classes in that school. We can write it like so:
$school=@{
name="Alkane High School"
class=@{
name="1AB"
teacher="Joe Bloggs"
}
}
$school | convertto-json
and this will output
{
"class": {
"teacher": "Joe Bloggs",
"name": "1AB"
},
"name": "Alkane High School"
}
Notice how the school name appears last, when we declared it first in our JSON object? We can correct that by specifying [ordered]
in front of the school hashtable like so:
$school=[ordered]@{
name="Alkane High School"
class=@{
name="1AB"
teacher="Joe Bloggs"
}
}
Giving us this output:
{
"name": "Alkane High School",
"class": {
"teacher": "Joe Bloggs",
"name": "1AB"
}
}
Do you also notice that the output for the class is not an array with square brackets, which implies there cannot be multiple classes in a school? We can fix this by either adding another class like so:
$school=[ordered]@{
name="Alkane High School"
class=@{
name="1AB"
teacher="Joe Bloggs"
},@{
name="2AB"
teacher="Peter Pan"
}
}
$school | convertto-json
Which now automatically creates the array [] since there is more than one class:
{
"name": "Alkane High School",
"class": [
{
"teacher": "Joe Bloggs",
"name": "1AB"
},
{
"teacher": "Peter Pan",
"name": "2AB"
}
]
}
Or, we can simply force PowerShell to use an array by prefixing the @ with a comma like so:
$school=[ordered]@{
name="Alkane High School"
class=,@{
name="1AB"
teacher="Joe Bloggs"
}
}
$school | convertto-json
Producing the following output:
{
"name": "Alkane High School",
"class": [
{
"teacher": "Joe Bloggs",
"name": "1AB"
}
]
}
Remember that we create JSON objects (the school) by using the syntax for a hashtable, which is simply: @{
When we want to create a JSON array [], we can prefix the @ with a comma ,@{
to force a JSON array.
Annoying Gotcha When Testing PowerShell with JSON
When our object becomes more complex with nested entries, we usually want to test the output using the convertto-json
cmdlet. Consider this nested example:
$school=[ordered]@{
name="Alkane High School"
class=,@{
name="1AB"
teacher="Joe Bloggs"
student=@{
"Name"="Peter"
},
@{
"Name"="Rachel"
}
}
}
$school | convertto-json
where the output is:
{
"name": "Alkane High School",
"class": [
{
"name": "1AB",
"teacher": "Joe Bloggs",
"student": "System.Collections.Hashtable System.Collections.Hashtable"
}
]
}
When i first saw this, I thought seeing System.Collections.Hashtable was some kind of error when creating JSON objects using PowerShell! But it wasn’t! We merely needed to increase the default depth when converting our JSON object like so!
$school | convertto-json -Depth 4
Using PowerShell to Write JSON
In this example, we first create a PowerShell object with some sample properties and nested objects. We then use the ConvertTo-Json
cmdlet to convert the PowerShell object to a JSON string. Finally, we use the Set-Content
cmdlet to save the JSON string to a file.
This example shows how to read and write JSON using PowerShell, and can be customized to fit the specific needs of your JSON data.
$obj = @{
"PropertyName" = "PropertyValue"
"ObjectName" = @{
"ObjectPropertyName" = "ObjectPropertyValue"
}
}
# Convert object to JSON
$json = $obj | ConvertTo-Json
# Save JSON to file
$json | Set-Content -Path C:\alkane\example.json
Using PowerShell to Read JSON
In this example, we first load a JSON file using the Get-Content
cmdlet and pass the -Raw
parameter to read the entire file as a single string. We then use the ConvertFrom-Json
cmdlet to convert the JSON string to a PowerShell object. We can then access specific properties within the JSON object using dot notation.
# Load JSON file
$json = Get-Content -Path C:\alkane\example.json -Raw | ConvertFrom-Json
# Access JSON properties
$json.PropertyName
$json.ObjectName.PropertyName
Using PowerShell to Iterate Through JSON
Let’s suppose our JSON file has more than one object with multiple properties (key/value pairs) like so:
$obj = @{
"ObjectName1" = @{
"Object1PropertyName1" = "Object1PropertyValue1"
"Object1PropertyName2" = "Object1PropertyValue2"
}
"ObjectName2" = @{
"Object2PropertyName1" = "Object2PropertyValue1"
"Object2PropertyName2" = "Object2PropertyValue2"
}
}
# Convert object to JSON
$json = $obj | ConvertTo-Json
# Save JSON to file
$json | Set-Content -Path C:\alkane\example.json
We might then want to loop through these objects and properties to read each value. We can do this like so:
# Load JSON file
$json = Get-Content -Path C:\alkane\example.json -Raw | ConvertFrom-Json
# Loop through the objects in the JSON data
foreach ($object in $json.PSObject.Properties) {
Write-Host "Object name: $($object.Name)"
$objectproperties = Get-Member -InputObject $object.Value -MemberType NoteProperty
foreach($property in $objectproperties) {
Write-Host "Property name: $($property.Name)"
Write-Host "Property value: $($object.Value.($property.Name))"
}
}
It’s also worth familiarising yourself with escaping quotes and backslashes in JSON.