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-Expression (alias 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-Expression cmdlet can easily be added as well.

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


The ConvertTo-Expression cmdlet converts any object to a PowerShell Object Notation (PSON) expression. The properties are converted to field names, the field values are converted to property values, and the methods are removed.

You can then use the ConvertFrom-Pson (Invoke-Expression) cmdlet to convert a PSON-formatted string to a PowerShell object, which is easily managed in Windows PowerShell.


The ConvertTo-Expression cmdlet is available from the github iRon7/ConvertTo-Expression repository and the central PowerShell Gallery repository:


PS> Save-Script -Name ConvertTo-Expression -Path <path>


PS> Install-Script -Name ConvertTo-Expression


ConvertTo-Expression [-Object] <Object> [[-Depth] <Int>] [[-Expand] <Int>] [[-Indent] <Int>] [[-IndentChar] <Char>] [[-SetType] <None|Native|Cast|Strict>] [[-NewLine] <String>]

<Object> | ConvertTo-Expression [-Depth] <Int> [-Expand] <Int> [-Indentation] <Int> [-IndentChar] <Char> [-SetType] <None|Native|Cast|Strict> [-NewLine] <String>


[-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)

[-Expand] <Int>

The expand option defines till what level the sub-item are expanded over separate lines. The default value is 9.

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

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

-Expand 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 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.

[-NewLine] <String>

Sets the characters for a new line. The default is the system’s newline default (Environment.NewLine).

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


Converting a custom object to a PSON expression

Converting a system object

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

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

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

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


The ConvertTo-Expression cmdlet was originally published at StackOverflow

Leave a Reply