Why and how are these two $null values different?

In particular, is $l_t2 really $null or not?

$l_t2 is not $null, but a [System.Management.Automation.Internal.AutomationNull]::Value. It is a special instance of PSObject. It is returned when a pipeline returns zero objects. That is how you can check it:

$a=&{} #shortest, I know, pipeline, that returns zero objects
$b=[System.Management.Automation.Internal.AutomationNull]::Value

$ReferenceEquals=[Object].GetMethod('ReferenceEquals')

$ReferenceEquals.Invoke($null,($a,$null)) #returns False
$ReferenceEquals.Invoke($null,($a,$b))    #returns True

I call ReferenceEquals thru Reflection to prevent conversion from AutomationNull to $null by PowerShell.

$l_t1 -eq $null returns nothing

For me it returns an empty array, as I expect from it.

$l_t2.count returns 0

It is a new feature of PowerShell v3:

You can now use Count or Length on any object, even if it didn’t have the property. If the object didn’t have a Count or Length property, it will will return 1 (or 0 for $null). Objects that have Count or Length properties will continue to work as they always have.

PS> $a = 42 
PS> $a.Count 
1

 

And why does $l_t2 suddenly seem to become “more $null” when it gets passed in the the function addToArray as a parameter???????

It seems that PowerShell converts AutomationNull to $null in some cases, like calling .NET methods. In PowerShell v2, even when saving AutomationNull to a variable it gets converted to $null.

Leave a Comment