powershellnull

What is the difference between $null and the empty output of Where-Object?


Consider the following:

$psversiontable # 7.4.6

$a = $null
$null -eq $a # Returns $true
$a.GetType() # You cannot call a method on a null-valued expression.
$b = $a.PSObject.Copy() # You cannot call a method on a null-valued expression.

$c = Get-Process | Where-Object { $_.Name -eq "oiawmij3209j23oifnoeicn" } # Matches nothing, should return nothing
$null -eq $c # Returns $true
$c.GetType() # You cannot call a method on a null-valued expression.
$d = $c.PSObject.Copy() # Works
$d.GetType() # PSCustomObject

My questions:

Thanks for your time.

Edit: a comment asked why I'm using the PSObject property. It's to avoid this problem:

# $hash2 is a "copy" of $hash1, but both variables actually just contain references to the same object in memory, so modifying $hash2 also modifies $hash1
$hash1 = @{ foo = "apple" }
$hash2 = $hash1
$hash2.bar = "banana"
Write-Host $hash1.bar # Returns "banana"

# $hash4 is a "real" copy of $hash3, i.e. each variable contains a reference to a different object in memory, thus modifying $hash4 does NOT also modify $hash3
$hash3 = @{ foo = "apple" }
$hash4 = $hash3.PSObject.Copy()
$hash4.bar = "banana"
Write-Host $hash3.bar # Returns nothing

In the relevant production code there may be better ways to work around this, but that's how I'm currently doing it, and what spawned the question.


Solution

  • This question was originally (and reasonably) closed as a duplicate of the following questions:

    However @mklement0 and others provide a lot of details in comments in this question which deserve to be captured in a more visible and collected answer, though they may be repeated somewhat in mklement0's answers to the other questions. As I (OP) am the learner in this situation, feel free to edit the answer/provide corrections.

    The core of this question (and the linked duplicates) revolves around the technical differences between $null and "automation null" ([System.Management.Automation.Internal.AutomationNull]::Value), a.k.a. "the enumerable null".

    To answer the direct questions in the OP:

    Further context: