This behavior is mystifying!
Consider the following PowerShell script:
[Reflection.Assembly]::LoadFrom("Newtonsoft.Json.dll") | Out-Null
function ConvertFrom-JsonNet {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string] $Json
)
$O = [Newtonsoft.Json.Linq.JObject]::Parse($Json)
Write-Host $O.GetType().Name
return $O
}
Clear-Host
$Json = '{"test":"prop"}'
$O1 = ConvertFrom-JsonNet '{"test":"prop"}'
$O2 = [Newtonsoft.Json.Linq.JObject]::Parse($Json)
Write-Host $O1.GetType().Name
Write-Host $O2.GetType().Name
You'd expect the output to be:
JObject
JObject
JObject
but it's not! It's:
JObject
JProperty
JObject
How is this possible? How is the type of the object within the function JObject, but then after it's passed out of the function, it's JProperty?
Sigh
Yay for PowerShell's inflexibility!
Apparently, PowerShell will "unroll" all collections that are destined for the pipeline. In this case,
JObjectimplementsICollection<KeyValuePair<string, JToken>>. TheJObject's collection contains a singleJProperty, which is what was being "unrolled" into the pipeline. I found this answer, which shows that rolling a collection into an outer collection will cause the intended value to be placed in the pipeline.Wouldn't it be nice if PowerShell had a mechanism for adding something to the pipeline untouched? :)