I have a function that converts a PSObject into a hashtable. Function works well, but there's a little subtlety that I am trying to understand and can't really grasp my head around.
I'm using PowerShell Core 7.0.3
The function:
function Convert-PSObjectToHashtable
{
param (
[Parameter(ValueFromPipeline)]
$InputObject
)
process
{
if ($null -eq $InputObject) { return $null }
if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string])
{
$collection = @(
foreach ($object in $InputObject) { Convert-PSObjectToHashtable $object }
)
# buggy
#Write-Output -NoEnumerate $collection
# correct
$collection
}
elseif ($InputObject -is [psobject])
{
$hash = @{}
foreach ($property in $InputObject.PSObject.Properties)
{
$hash[$property.Name] = Convert-PSObjectToHashtable $property.Value
}
$hash
}
else
{
$InputObject
}
}
}
I execute the following code:
$obj = "{level1: ['e','f']}"
$x = $obj | ConvertFrom-Json | Convert-PSObjectToHashtable
[Newtonsoft.Json.JsonConvert]::SerializeObject($x)
The "buggy" code returns me:
{"level1":{"CliXml":"<Objs Version=\"1.1.0.1\" xmlns=\"http://schemas.microsoft.com/powershell/2004/04\">\r\n <Obj RefId=\"0\">\r\n <TN RefId=\"0\">\r\n <T>System.Object[]</T>\r\n <T>System.Array</T>\r\n <T>System.Object</T>\r\n </TN>\r\n <LST>\r\n <S>e</S>\r\n <S>f</S>\r\n </LST>\r\n </Obj>\r\n</Objs>"}}
The correct code returns me:
{"level1":["e","f"]}
Why wouldn't the buggy code work, if technically, in PowerShell when working with the object result, they look equivalent?
Thank you!