How to Use PowerShell 7 to Work with JSON Files

Though there are many file formats used for configuration and data storage. JSON, or JavaScript Object Notation, files have become very common. They offer an easy to understand and compact format to define information. In addition, they integrate exceptionally well within PowerShell. One of its powerful functions is the PowerShell import JSON, allowing JSON data to be imported as pipelinable objects that can be subsequently exported.

What’s changed in PowerShell 7 to enhance support for JSON? There are no new cmdlets, but there have been some functionality changes to the existing cmdlets.

JSON Support in PowerShell

Before diving into the new functionality, how does PowerShell work with JSON? Let’s walk through a few examples. We will explore how to import JSON, manipulate an object, and export the JSON to a file that can be later consumed.

Import JSON into PowerShell

First, we want to consume a JSON file and then update the values for later use. This type of technique is often used when storing information about a given system, for example, the computer name, environmental properties, etc. In this example, we are going to use a simple JSON file.

computer.json

{
  "SystemName": "TestSystem",
  "LastBoot": "3/28/2020 11:27:15 AM",
  "User": "TestUser",
  "LoggedOn": true
}

By retrieving the content of the JSON file and then converting that content from JSON, a standard PowerShell object is output.

Get-Content -Path "D:computer.json" | ConvertFrom-JSON
Untitled 97

How is the object actually seen by PowerShell? When the JSON is imported, PowerShell converts the data into a PSCustomObject and attempts to match the properties into their types, such as string or bool types. The strength of PowerShell import JSON lies in this seamless conversion process.

Untitled 98

Exporting JSON Data from PowerShell

Similar to importing JSON, we are able to export a PowerShell object that has been modified or changed. Adding to our above example, what if we want to add a property to our existing imported JSON, such as the PowerShell version. After we save our imported content to a variable, we can then add on a new property.

$JSON = Get-Content -Path "D:computer.json" | ConvertFrom-JSON
$JSON | Add-Member -Name "PSVersion" -MemberType NoteProperty -Value "7.0"
Untitled 99

Now that we have added the new property to our object, let’s export this object and overwrite our existing JSON file, showcasing the full circle PowerShell import JSON process along with export functionalities.

$JSON | ConvertTo-JSON | Out-File "D:computer.json"
Untitled 100

As you can tell, the new property PSVersion has been added and can be appropriately updated as necessary.

Testing our JSON

In any script or function, it is crucial to test the input and output to make sure that the data is not corrupted or that it will cause further issues down the line. Thankfully, PowerShell added Test-JSON in version 6.x. We have two options, pass in a file as a string that Test-JSON can operate on, or a pass a string from the command-line itself.

Get-Content -Path "D:computer.json" -Raw | Test-JSON
Untitled 2020 03 29T112847.839

Note that Get-Content is using the Raw parameter. This returns the file content as one single string instead of an array of strings which Test-JSON cannot process.

What if we want to send in just a simple JSON string to make sure that it’s valid before we save the data? Thankfully, this is also very simple to do with Test-JSON.

'{
  "SystemName": "TestSystem",
  "LastBoot": "3/28/2020 11:27:15 AM",
  "User": "TestUser",
  "LoggedOn": true,
  "PSVersion": "7.0"
}' | Test-JSON
Untitled 2020 03 29T112913.436

New Features in PowerShell 7

Now that you know how to work with JSON in PowerShell, what does version 7 bring to the table to help enhance support for JSON data? There are a few new parameters available for ConvertTo-JSON and ConvertFrom-JSON that will help with edge cases and the transformation of JSON data.

ConvertTo-JSON

There are two new parameters available as seen below.

  • EnumsAsStrings
  • AsArray

EnumsAsStrings

Although not typically used as much in PowerShell, an enum is a structured data type that enables a variable to be a set of predefined constants. When referencing an enum, the resulting value is a zero-based index. When outputting an enum value from PowerShell to JSON, the numerical value itself would be output, which isn’t always ideal. Often, the string name of the enum would be preferable.

Untitled 2020 03 29T112956.652

Without the EnumsAsStrings parameter defined, we can see just the values being output.

Untitled 2020 03 29T113012.603

With the EnumsAsStrings parameter, the correct string names are shown.

Untitled 2020 03 29T113030.702

AsArray

Similar to how the EnumsAsStrings works, AsArray will wrap pipeline input as an array whether or not it is a single item or multiple items.

Untitled 2020 03 29T113047.906

ConvertFrom-JSON

Just like ConvertTo-JSON, ConvertFrom-JSON has added a new parameter and changed some functionality.

  • NoEnumerate

NoEnumerate

Prior to PowerShell 7 the default behavior of ConvertFrom-JSON was to not unwrap collections by default. This meant that if a JSON array was passed into PowerShell it would be seen as a single object and not as multiple objects.

# PowerShell 5.1
PS> ('["first","second","third"]' | ConvertFrom-JSON | Measure-Object).Count
1

In PowerShell 7, the new behavior is to unwrap collections which is much more in line with how most cmdlets and functions work within PowerShell.

Image # Expand
Untitled 2020 03 29T113114.622

By using the NoEnumerate property, this will change the default behavior back to the original method used prior to PowerShell 7.

Image # Expand
Untitled 2020 03 29T113138.754

Changed Depth Behavior

One final note on ConvertFrom-JSON, the Depth parameter now allows much larger values than it did prior to PowerShell 7. Starting in PowerShell 7, the depth now has a default of 1024 but allows up to [Int]::MaxValue which is a vast difference from the 101 limit that older versions of PowerShell had.

Conclusion

Using and manipulating JSON content in PowerShell is easy to do and offers any number of ways to transform the data to meet your exact needs. Many of the additions that have been added in recent years are community requested additions to make working with JSON that much easier. PowerShell 7 has continued that tradition and expanded even further on the usefulness of the built-in PowerShell JSON functionality.

FAQs

How can I validate if my PowerShell import JSON operation was successful without using Test-JSON?

You can verify a successful PowerShell import JSON operation by using try-catch blocks, checking the object properties with Get-Member, or utilizing the $? automatic variable which indicates the success status of the last operation. Additionally, you can pipe the imported JSON to Select-Object to ensure all expected properties are present.

What are the performance considerations when using PowerShell import JSON with large files?

When performing PowerShell import JSON operations on large files, consider using StreamReader instead of Get-Content, implement pagination if possible, use -Raw parameter for better memory management, and utilize PowerShell jobs for parallel processing of multiple JSON files.

Can I use PowerShell import JSON to merge multiple JSON files into a single object?

Yes, you can merge multiple JSON files by using PowerShell import JSON operations in a loop, combining the objects with Add-Member or the += operator, and then creating a new consolidated JSON file. This is particularly useful for configuration management and data consolidation tasks.

How do I handle special characters when using PowerShell import JSON operations?

To handle special characters in PowerShell import JSON operations, use UTF8 encoding with -Encoding parameter, escape special characters properly, and consider using the [System.Web.HttpUtility]::HtmlDecode() method for HTML-encoded content within your JSON files.

What are the best practices for error handling during PowerShell import JSON operations?

Implement comprehensive error handling for PowerShell import JSON operations by using try-catch blocks with specific error types, validating JSON schema before import, implementing logging mechanisms, and using the -ErrorAction parameter to control how PowerShell handles errors during import operations.