PowerShell not returning null

RJames2010 36 Reputation points
2023-12-12T15:05:16.3266667+00:00

I'm not new to PowerShell and I even asked a colleague who also has a lot of experience with PS and neither of us understand why this little test code snippet, if it doesn't find a match in the array, returns something other than $null - it doesn't return blank ("") either. I'm missing something dumb and haven't been able to figure it out. To me, if you set a var to $null and it can't be populated, then it should be $null.

ForEach($Rec in $Old){
    $NoMatch = $null
    $NoMatch = $New.Where({$_.Name -eq $Rec.Name})
    
    If($NoMatch -ne $null){
        Write-host "Deleted"
        }
    
    }
Windows for business | Windows Server | User experience | PowerShell
0 comments No comments
{count} votes

Accepted answer
  1. Luis Arias 8,621 Reputation points Volunteer Moderator
    2023-12-12T16:20:11.73+00:00

    Hi RJames2010,

    This is the expected behaviour , due to the where method and cmdlet always returns a collection, which can be empty if there are no matches. That you can do if check if the collection is empty:

    $numbers = 1..5
    $noMatch = $numbers.Where({$_ -eq 6})
    ($noMatch | Get-Member).TypeName
    
    # Count because is a collection
    
    if ($noMatch.Count -eq 0) {
    	Write-Host "The collection is empty."
    } else {    
    	Write-Host "The collection is not empty."
    }
    
    # Test with $null It won't work
    
    if ($null -eq $noMatch) {
    	Write-Host "The collection is empty."
    } else {    
    	Write-Host "The collection is not empty."
    }
    
    
    

    As example If $noMatch is empty prints “The collection is empty.” However this is always not null.

    References:

    Let me know if this solve your doubt.

    Luis


1 additional answer

Sort by: Most helpful
  1. Rich Matheisen 47,901 Reputation points
    2023-12-12T16:46:54.5633333+00:00

    Try rewriting this line: If($NoMatch -ne $null){ to If($null -ne $NoMatch){.

    When you place the array on the left side of the comparison operator each element in the array is compared to $null. If any of the array elements is $null then the comparison returns the matching element(s). This happens because PowerShell applies array behavior to the array and it streams each element to the comparison. So, you aren't comparing the array to $null, you're comparing the arrays elements to $null.

    If the "New" object (or class) returns an array with zero elements it's still an array. I.e., an empty array is still an array -- but the set of array elements is $null!

    You can avoid this perplexing sort of problem by ALWAYS placing $null on the lefthand side of a comparison operator.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.