Public/ConvertTo-PSON.ps1
function ConvertTo-PSON { <# .SYNOPSIS creates a powershell object-notation script that generates the same object data .DESCRIPTION This produces 'PSON', the powerShell-equivalent of JSON from any object you pass to it. It isn't suitable for the huge objects produced by some of the cmdlets such as Get-Process, but fine for simple objects .EXAMPLE $array=@() $array+=Get-Process wi* | Select-Object Handles,NPM,PM,WS,VM,CPU,Id,ProcessName ConvertTo-PSON $array .PARAMETER Object the object that you want scripted out .PARAMETER Depth The depth that you want your object scripted to .PARAMETER Nesting Level internal use only. required for formatting #> [CmdletBinding()] param ( [parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)] [AllowNull()] $inputObject, [parameter(Position = 1, Mandatory = $false, ValueFromPipeline = $false)] [int]$depth = 16, [parameter(Position = 2, Mandatory = $false, ValueFromPipeline = $false)] [int]$NestingLevel = 1, [parameter(Position = 3, Mandatory = $false, ValueFromPipeline = $false)] [int]$XMLAsInnerXML = 0 ) BEGIN { } PROCESS { If ($inputObject -eq $Null) { $p += '$Null'; return $p } # if it is null return null $padding = [string]' ' * $NestingLevel # lets just create our left-padding for the block $ArrayEnd = 0; #until proven false try { $Type = $inputObject.GetType().Name # we start by getting the object's type if ($Type -ieq 'Object[]') { $Type = "$($inputObject.GetType().BaseType.Name)" } # see what it really is if ($depth -ilt $NestingLevel) { $Type = 'OutOfDepth' } #report the leaves in terms of object type elseif ($Type -ieq 'XmlDocument' -or $Type -ieq 'XmlElement') { if ($XMLAsInnerXML -ne 0) { $Type = 'InnerXML' } else { $Type = 'XML' } } # convert to PS Alias # prevent these values being identified as an object if (@('boolean', 'byte', 'char', 'datetime', 'decimal', 'double', 'float', 'single', 'guid', 'int', 'int32', 'int16', 'long', 'int64', 'OutOfDepth', 'RuntimeType', 'PSNoteProperty', 'regex', 'sbyte', 'string', 'timespan', 'uint16', 'uint32', 'uint64', 'uri', 'version', 'void', 'xml', 'datatable', 'Dictionary`2' 'SqlDataReader', 'datarow', 'ScriptBlock', 'type') -notcontains $type) { if ($Type -ieq 'OrderedDictionary') { $Type = 'HashTable' } elseif ($Type -ieq 'List`1') { $Type = 'Array' } elseif ($Type -ieq 'PSCustomObject') { $Type = 'PSObject' } # elseif ($inputObject -is "Array") { $Type = 'Array' } # whatever it thinks it is called elseif ($inputObject -is "HashTable") { $Type = 'HashTable' } # for our purposes it is a hashtable elseif ($inputObject -is "Generic") { $Type = 'DotNotation' } # for our purposes it is a hashtable #elseif ((gm -inputobject $inputObject -membertype Methods | Select name|where name -like 'GetEnumerator') -ne $null) { $Type = 'HashTable' } elseif (($inputObject | gm -membertype Properties | Select name | Where name -like 'Keys') -ne $null) { $Type = 'DotNotation' } #use dot notation elseif (($inputObject | gm -membertype Properties | Select name).count -gt 1) { $Type = 'Object' } } write-verbose "$($padding)Type:='$Type', Object type:=$($inputObject.GetType().Name), BaseName:=$($inputObject.GetType().BaseType.Name) $NestingLevel " switch ($Type) { 'ScriptBlock'{ "[$type] {$($inputObject.ToString())}" } 'InnerXML' { "[$type]@'`r`n" + ($inputObject.OuterXMl) + "`r`n'@`r`n" } # just use a 'here' string 'DateTime' { "[datetime]'$($inputObject.ToString('s'))'" } # s=SortableDateTimePattern (based on ISO 8601) local time 'Boolean' { "[bool] $(&{ if ($inputObject -eq $true) { "`$True" } Else { "`$False" } })" } 'string' { if ($inputObject -match '[\r\n]') { "@'`r`n$inputObject`r`n'@" } else { "'$($inputObject -replace '''', '''''')'" } } 'Char' { [int]$inputObject } { @('byte', 'decimal', 'double', 'float', 'single', 'int', 'int32', 'int16', 'long', 'int64', 'sbyte', 'uint16', 'uint32', 'uint64') -contains $_ } { "$inputObject" } # rendered as is without single quotes 'PSNoteProperty' { "$(ConvertTo-PSON -inputObject $inputObject.Value -depth $depth -NestingLevel ($NestingLevel))" } 'Array' { "`r`n$padding@(" + ("$($inputObject | ForEach { $ArrayEnd = 1; ",$(ConvertTo-PSON -inputObject $_ -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd)) + "`r`n$padding)" } 'HashTable' { "`r`n$padding@{" + ("$($inputObject.GetEnumerator() | ForEach { $ArrayEnd = 1; "; '$($_.Name)' = " + (ConvertTo-PSON -inputObject $_.Value -depth $depth -NestingLevel ($NestingLevel + 1)) })".Substring($ArrayEnd) + "`r`n$padding}") } 'PSObject' { "`r`n$padding[pscustomobject]@{" + ("$($inputObject.PSObject.Properties | ForEach { $ArrayEnd = 1; "; '$($_.Name)' = " + (ConvertTo-PSON -inputObject $_ -depth $depth -NestingLevel ($NestingLevel + 1)) })".Substring($ArrayEnd) + "`r`n$padding}") } 'Dictionary' { "`r`n$padding@{" + ($inputObject.item | ForEach { $ArrayEnd = 1; '; ' + "'$_'" + " = " + (ConvertTo-PSON -inputObject $inputObject.Value[$_] -depth $depth -NestingLevel $NestingLevel+1) }) + '}' } 'DotNotation'{ "`r`n$padding@{" + ("$($inputObject.Keys | ForEach { $ArrayEnd = 1; "; $_ = $(ConvertTo-PSON -inputObject $inputObject.$_ -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "`r`n$padding}") } 'Dictionary`2'{ "`r`n$padding@{" + ("$($inputObject.GetEnumerator() | ForEach { $ArrayEnd = 1; "; '$($_.Key)' = " + (ConvertTo-PSON -inputObject $_.Value -depth $depth -NestingLevel ($NestingLevel + 1)) })".Substring($ArrayEnd) + "`r`n$padding}") } 'Object' { "`r`n$padding@{" + ("$($inputObject | Get-Member -membertype properties | Select-Object name | ForEach { $ArrayEnd = 1; "; $($_.name) = $(ConvertTo-PSON -inputObject $inputObject.$($_.name) -depth $NestingLevel -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "`r`n$padding}") } 'XML' { "`r`n$padding@{" + ("$($inputObject | Get-Member -membertype properties | where name -ne 'schema' | Select-Object name | ForEach { $ArrayEnd = 1; "; $($_.name) = $(ConvertTo-PSON -inputObject $inputObject.$($_.name) -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "`r`n$padding}") } 'Datatable' { "`r`n$padding@{" + ("$($inputObject.TableName)=`r`n$padding @(" + "$($inputObject | ForEach { $ArrayEnd = 1; ",$(ConvertTo-PSON -inputObject $_ -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "`r`n$padding )`r`n$padding}") } 'DataRow' { "`r`n$padding@{" + ("$($inputObject | Get-Member -membertype properties | Select-Object name | ForEach { $ArrayEnd = 1; "; $($_.name)= $(ConvertTo-PSON -inputObject $inputObject.$($_.name) -depth $depth -NestingLevel ($NestingLevel + 1))" })".Substring($ArrayEnd) + "}") } default { "'$inputObject'" } } } catch { write-error "Error'$($_)' in script $($_.InvocationInfo.ScriptName) $($_.InvocationInfo.Line.Trim()) (line $($_.InvocationInfo.ScriptLineNumber)) char $($_.InvocationInfo.OffsetInLine) executing $($_.InvocationInfo.MyCommand) on $type object '$($inputObject.Name)' Class: $($inputObject.GetType().Name) BaseClass: $($inputObject.GetType().BaseType.Name) " } finally { } } END { } } |