PowerShell Pipeline
A Look at JSON and PowerShell
Here's how to convert objects to and from the text format in the latest PowerShell version.
If you are not familiar with JSON, it stands for Java Script Object Notation and is an open standard format that uses human readable text for data interchanges. Despite its name, it is separate to JavaScript and many languages have parsers suitable for working with it. Of course, PowerShell is no different in this arena with a couple of cmdlets (available since PowerShell V3) that are available to both convert to and convert from this format.
What about using XML to handle this type of data? Well, that is a hotly debated topic (a quick 'XML vs. JSON' search will show you that) and I will steer clear of that here. What you should know is that PowerShell can easily work between either of these approaches with its parser, so the choice is yours!
Before we start showing off using PowerShell to work with JSON, let's take a look at how the data is handled. The simplest look at the JSON data is by the property header and the value:
{
"string": Value
}
Note that the colon (:) is used to show that the value belongs to the header. Working with an array in JSON should look something like the following:
{
"string": [
Value1,
Value2
]
}
Using the square brackets ([,]) show the parser that this is an array. This information is useful when you are working with more complex objects and want to ensure that you properly put together the data in order for it to be parsed correctly, such as in this example:
{
"string": [
{
"string": "Value1"
},
{
"string": "Value2"
}
]
}
Some gotchas with JSON to watch out for include working with Boolean values: $True and $False. While in PowerShell, we know that we can just use $True and $False to make Boolean values, but in JSON, you must use lower case 'true' and 'false' in order to be properly identified as a Boolean value. Null behaves the same way, don't use Null or $Null but instead keep to the lower case 'null' instead.
Ok, now that we have covered some of the basics of JSON, it is time to take a look at the two cmdlets which are available in PowerShell: ConvertTo-JSON and ConvertFrom-JSON. These cmdlets, as you can tell, perform conversions of data either to JSON (if the incoming data is formatted properly) or converting an object to the JSON format.
ConvertTo-JSON
I'll start off showing ConvertTo-JSON and how we can use it to convert any object to the JSON format that can be used for anything that is expecting this format, such as a web service. The parameters for the cmdlet are shown in the image below.
As you can tell, there are not a lot of parameters here to deal with, but the ones to take note of are –Compress and –Depth. Compress simply takes the outputted JSON data and, as it says, compresses it down to fewer lines. Also note that the output that you receive is going to be string.
Before compression:
Get-ChildItem -File |
Select-Object -First 1 -Property Name, Fullname, Length |
ConvertTo-Json
After compression:
Get-ChildItem -File |
Select-Object -First 1 -Property Name, Fullname, Length |
ConvertTo-Json -Compress
In this case, it takes the output down from using 5 lines to a single line.
Depth is pretty self-explanatory as it will only do down to the specified depth of an object and output that data. If an object happens to have more nested object within it, it will only parse down to the desired depth.
As we have already covered some of the output with ConvertTo-JSON in my previous example, I will show another example highlighting nested objects as well as how it shows null and Boolean values and a few other cool things.
Get-ChildItem -File |
Select-Object -First 1 |
ConvertTo-Json -Depth 1
There is a lot happening here. This is a single file object shown here that not only has nested objects, but also shows the 'null' and the Boolean values which are also lowercase when converted to JSON. Also take note of the dates here. They are not the human readable dates that we are used to here. Instead they are being shown differently using a Date() function. Another thing to note is that backslashes are being escaped here by another backslash.
ConvertFrom-JSON
The opposite of ConvertTo-JSON in that this will take something that is in the JSON format and convert it to a PowerShell object that we can use for whatever we need to it do. The parameters for this cmdlet are shown below.
All we need to do is supply the properly formatting JSON data and the cmdlet will do the rest for us. If you recall some of the examples that I showed earlier in this article, we can apply those here as well. The only thing that we need to do is to wrap these in a here-string so they can be properly parsed into an object. Note that this will convert the object to a System.Management.Automation.PSCustomObject object, regardless of what the object was before being a JSON formatted string. Now let's take a quick look at some examples of passing some JSON formatted strings to this cmdlet and getting some results back starting with the simplest approach.
@"
{
"Test": 1234
}
"@ | ConvertFrom-Json
Now for something more complex:
@"
{
"FirstName": "Bob",
"LastName": "Smith",
"Age": 40,
"DOB": {
"Month": "March",
"Day": 20,
"Year": 1975
},
"Hobbies": [
"Swimming",
"PowerShell",
"Movies"
],
"IsHuman": true,
"LastUpdate": "\/Date(1445212320855)\/"
}
"@ | ConvertFrom-Json
With that, we have covered the ways we can use the *-JSON cmdlets to both convert to an object to JSON but also to convert some JSON formatted data to a PowerShell object. Now you can use this if you need to provide this type of formatted data to a web service or as another means to storing data to use later on.
About the Author
Boe Prox is a Microsoft MVP in Windows PowerShell and a Senior Windows System Administrator. He has worked in the IT field since 2003, and he supports a variety of different platforms. He is a contributing author in PowerShell Deep Dives with chapters about WSUS and TCP communication. He is a moderator on the Hey, Scripting Guy! forum, and he has been a judge for the Scripting Games. He has presented talks on the topics of WSUS and PowerShell as well as runspaces to PowerShell user groups. He is an Honorary Scripting Guy, and he has submitted a number of posts as a to Microsoft's Hey, Scripting Guy! He also has a number of open source projects available on Codeplex and GitHub. His personal blog is at http://learn-powershell.net.