JSON and PowerShell

Working with Object-based arrays in PowerShell can be a challenge; but here's a trick that will allow you to manipulate these objects efficiently.

JSON and PowerShell

Why does something that seems so simple in concept become such a challenge in PowerShell?

Say you have this JSON Object in a file or just in memory somewhere:

Example JSON file with three sub-elements under a 'resources' subkey

It should be relatively easy to for example remove the third resources element in its entirety. But PowerShell does not allow you to do that in a way that would be straightforward.

You would think that you could simply import the JSON into an Array (ConvertFrom-JSON) and then perform something like this to remove the element in question:

The Remove method doesn't work on structured object-based arrays like JSON objects.

Alas, anyone that has had experience trying to work with imported arrays and JSON within PowerShell will be familiar with this little chestnut...

The ever familiar "Collection was of a fixed size." exception.

"Collection was of a fixed size" is the bane of many a PowerShell scripter and through hours and hours of research online, I haven't found a single article that shows how this can be avoided with structured arrays such as JSON. Arrays built from data sources and not dynamically generated can have elements modified, however it doesn't support the Add or Remove methods.

Most blogposts I was able to find suggest using the method of iterating through each array element, which is fine for unstructured or single-depth arrays, but with something like nested arrays that make up JSON objects, with named array elements, these methods don't work well, or at all in this case.

Fortunately, there is another way. After much stumbling, I came across the command 'Select-Object', which is normally used to allow you to select specific columns in tables. And that is the key... tables. By using the Select-Object cmdlet, the structured data is converted into objects (tables are an example of this) in the background. Once the data is in this format, you can simply use a piped 'Where' statement in which you can select or exclude the element based on a search parameter. With that in mind, it's very similar to a SELECT statement you'd commonly use in SQL.

PowerShell Code to update the list of elements in an array sub-object using the Select-Object cmdlet

In this case, using the Select-Object cmdlet on the Resources subkey of the $myJSON array, with a Where statement to include on the the objects without the name indicated by $DeathString, and then storing that back in $myJson.Resources.

That's the other trick I discovered during this process, you can replace a subkey in an array with another subkey. Being able to replace $myJson.Resources with a reconstructed $myJson.Resources is essentially iterating the items in the array and removing the ones we don't want, but it does it at an object level. Treating the array elements as objects and interacting with them as objects is the best way to interact with JSON arrays in PowerShell.

This same approach can be used with any structured array data within PowerShell but as JSON is incredibly popular and heavily used in programming and in particular online and cloud development, tools like this will be very useful indeed.

On an aside, I really like the $DeathString variable. I was watching Harry Potter when I wrote this and it seemed quite fitting.