PowerShell has a few cmdlets to convert (complex) objects to a string. This is called serialization or stringification. Examples are:

Besides there are a few cmdlets to do the opposite and convert the string back to a (complex) object. This is called deserialization or parsing. Examples are:

But there is no standard cmdlet that lets you convert an object to a PowerShell Object Notation (PSON), yet there exists actually already a kind of ConvertFrom-PSON in the form of: Invoke-Expression. The  Invoke-Expressioncmdlet evaluates or runs a specified string as a command and returns the results of the expression or command. This means that the only thing required is a cmdlet which can do the opposite: serialize an object to a PSON string that can be read back with Invoke-Expression (which could be aliased to: ConvertFrom-PSON). At the same time, Invoke-Expression is a good praktisch to test the integrity of a ConvertTo-PSON cmdlet; it shouldn’t produce any error, all (embedded) objects and values should be read back and the datatypes should match the source as much as possible. Note here that not all datatypes can be converted and converted back, simply because you can’t assume that the required constructor exists on every other system. Due to this, system objects are converted to PSCustomObject objects which usually react the same with regards property references. Saying that, in general, PSON is better capable of handling native PowerShell object types as e.g. [Boolean][Char] and [DateTime] than JSON, but  the downside to this is that it can’t interchange data with other programming languages (yet?). An other advantage of PSON is that Invoke-Expression is also available in older PowerShell versions were the ConvertTo-PSON cmdlet can easily be added as well.

Besides serializing objects to a string, the ConvertTo-PSON cmdlet can come in handy for revealing and logging datatypes and structures of (embedded) objects and values.



ConvertTo-PSON [-Object] <Object> [[-Depth] <Int>] [[-Layers] <Int>] [[-Indent] <Int>] [[-IndentChar] <Char>] [[-SetType] <None|Native|Cast|Strict>]

<Object> | ConvertTo-PSON [-Depth] <Int> [-Layers] <Int> [-Indentation] <Int> [-IndentChar] <Char> [-SetType] <None|Native|Cast|Strict>


[-Object] <Object>

The object(s) to be converted to a PowerShell Object Notation string.

[-Depth] <Int>

Specifies how many levels of contained objects are included in the PSON representation. The default value is 9. A depth of 0 levels will remove the double quotes from strings this might come in handy where you expect a string but would like to be alerted when it is not, e.g.:

Write-Host "User name:" (PSON $UserName 0)

[-Layers] <Int>

The layers option will define how the layer levels will expanded over separate lines. Each layer level will be get an extra tab indent. The default value is 9.

-Layers 0: A single line (no linefeed) without any spaces (compressed mode)

-Layers 1: A single line (no linefeed) formatted with spaces

-Layers N: Multiple layers are formatted with spaces and expanded over multiple lines until a depth of N levels is reached . Each embedded object is indented with repeating characters defined by the -IndentChar parameter. The number of repeating characters is defined by the depth multiplied by the -Indentationparameter.

[-Indentation] <Int>

Defines how many IndentChars, defined by the IndentChar parameter,  to write for each level in the hierarchy when

[-IndentChar] <Char>

The character to use for indenting. The default is a tab character.

[-SetType] <None|Native|Cast|Strict>

Defines how the explicite the objecttype is being parsed:

-SetType None: No type information will be added to the (embedded) objects and values in the PSON string. This means that objects and values will be parsed to any of these data types when reading them back with ConvertFrom-PSON(Invoke-Expression): a numeric value, a [String] ('...'), an [Array] (@(...))  or a [HashTable] (@{...})

-SetType Native: The original type prefix is added to the (embedded) objects and values in the PSON string.
Note that most system (.Net) objects can’t be read back with ConvertFrom-PSON(Invoke-Expression), but -SetType Name can help to reveal (embedded) object types and hierarchies.

-SetType Cast: The type prefix is only added to (embedded) objects and values when required and optimized for read back with ConvertFrom-PSON(Invoke-Expression) by e.g. converting system (.Net) objects to PSCustomObject objects. Numeric values won’t have a strict type and therefor parsed to the default type that fits the value when read back with ConvertFrom-PSON(Invoke-Expression).

-SetType Strict: All (embedded) objects and values will have an explicit type prefix optimized for read back with ConvertFrom-PSON(Invoke-Expression) by e.g. converting system (.Net) objects to PSCustomObject objects.

For information on ConvertFrom-PSON, refer to Invoke-Expression.


Converting a custom object to PSON

Converting a system object

Convert (serialize) the WinLogon process to a PSON string:

$WinLogonPSON = Get-Process "WinLogon" | ConvertTo-PSON

Convert (de-serialize) the WinLogon PSON string back to an object:

$WinLogon = $WinLogonPSON | ConvertFrom-PSON  (or:  $WinLogon = $WinLogonPSON | Invoke-Expression)


The ConvertTo-PSON cmdlet was originally published at StackOverflow

Leave a Reply