Home > Software engineering >  PowerShell 5.1 : Where-Object returns an empty object that equals null
PowerShell 5.1 : Where-Object returns an empty object that equals null

Time:08-04

I am working on a script in PowerShell 5.1 and I got a issue that I cannot really make sense of :

@{test=@() | Where-Object {$_ -ne $null}} | ConvertTo-Json -Compres

returns

{"test":{}}

Yet

$null -eq (@() | Where-Object {$_ -ne $null})

is True

Why does ConvertTo-Json returns an empty object on a null pipe result ?

CodePudding user response:

Two issues at play here. First, an empty pipeline is not the same thing as $null, as explained in "Why is an empty PowerShell pipeline not the same as null?" @{test=@() | Where-Object {$_ -ne $null}} produces a hash table with a test key that has an AutomationNull value, not $null.

Second, there's a bug in PowerShell prior to 7.0 where AutomationNull is serialized as an empty object rather than $null, as reported in "ConvertTo-Json unexpectedly serializes AutomationValue.Null as an empty object, not null" (powershell#9231).

To work around this bug in older versions, you can coerce the AutomationNull to a real $null by inserting a psobject cast, which will then result in the value serializing properly:

@{test=[psobject](@() | Where-Object {$_ -ne $null})} | ConvertTo-Json -Compres
  • Related