This time we will take a look at how PowerShell can handle a nonexistent variable, the so called NULL value. Developers know this concept well, so here we will look at PowerShell’s approach to it. In a best case scenario, not handling or wrongly handling NULL values will cause the script to stop unexpectedly. It can however also damage data and cause unforeseen consequences and losses. To get an idea, Google the name Joseph Tartaro. This was a man who ordered a custom car number plate – “NULL”. Shortly afterwards, he started receiving all traffiic violation tickets in situations where the number plate of the vehicle was not known or was not entered into the database.
NULL, therefore, is an unknown or empty value. A variable in a script is NULL until we give it a value.
PowerShell also contains a $null variable, which represents the aforementioned NULL and we can use it to set values to other variables, compare values and for NULL values in collections, where PowerShell treat $null as an object, which sets it apart from most programming languages.
The most common use of $null is comparing values, where we are checking if a variable has already been assigned a value. For example:
PS>$null -eq $undefinedVariable
True
Sometimes when we write code, we can make a typo. PowerShell sees that uncorrectly written name as a new variable, which of course doesn’t have a value – it is NULL.
We can also find $null values in commands that don’t return any results:
PS> function Get-Nothing {}
PS> $value = Get-Nothing
PS> $null -eq $value
True
If we are using $null in text variables, it will be represented with an empty string:
PS>$value=$null
PS>write-output »Value is ($value)«
Value is ()
When $null is used in a numeric equation, the result will be incorrect or we will receive an error. In some cases, $null will be treated as 0, in other cases, the result will be $null. Usually, this depends on the order of values in the equation:
PS> $null * 5
PS> $null -eq ( $null * 5 )
True
PS> 5 * $null
0
PS> $null -eq ( 5 * $null )
False
Lists allow us to access values based on their index. If we attempt to do this on an undefined list, we will of course receive an error.
PS> $value = $null
PS> $value[10]
Cannot index into a null array.
At line:1 char:1
If we have a defined list and attempt to access an element that is not on the list, we get a $null value.
$array = @( 'one','two','three' )
$null -eq $array[100]
True
When referencing an object property that an object doesn’t have, PowerShell returns $null, the same as in the case of an undefined variable.
PS> $null -eq $undefined.madeUpProperty
True
PS> $date = Get-Date
PS> $null -eq $date.madeUpProperty
True
After referencing the method of a $null object the good times come to an end and we receive an error.
PS> $value = $null
PS> $value.toString()
You cannot call a method on a null-valued expression.
Everytime I see the message “You cannot call a method on a null-valued expression” I immediately look for places wbere I am calling a method on a variable without first checking it for $null.
In all cases above, we used $null on the left side of the comparison, for example:
If $null -eq $vrednost
This is on purpose and is a PowerShell best practice. Using $null on the right side sometimes leads to an unexpected result.
if ( $value -eq $null )
{
'List is $null'
}
if ( $value -ne $null )
{
'List is not $null'
}
If we do not define the $value variable, the above written code will return “List is $null”. Let’s take a look at a special case where the list is defined and contains $null.
$value = @( $null )
In this case none of the conditions above will be $true. When using the -eq operator, PowerShell will compare every element in the list and find $null. The -ne operator will also return $false, as it will search for everything that is different from $null and in this case it is a defined, not empty list.
If we pipe $null into a ForEach-Object cmdlet, it will generate a cycle and we cannot use it for non-existing values.
PS> ".txt", $null, ".pdf" | Foreach {"test"}
test
test
test
When checking for $null values (meaning checking for the absence of values) we have to pay attention to the data source. All data sources don’t have the same definition of $null. We need to check $null, [String]::Empty, FDBNull]::Value and [System.Management.Automation.Language.Null
String]::Value. Depending on the case we are dealing with, of course.