Learn the difference between a null, empty string, and white space value for a PowerShell variable and how to test for them.
PowerShell variables without “value”
More often than not, we create variables with the intent they will hold a value. We typically then choose to act upon that value. Therefore, if a variable doesn’t have value, this is something we would want to check against in our conditional logic flow.
However, not having a value may mean a couple of different things:
- Our variable may truly be absent of a value, and therefore its “value” is $null, an Automatic Variable in PowerShell which can “represent an absent or undefined value in commands and scripts.” This could apply to any variable that we declare but for which we do not set a value.
- If our variable is a string, it could contain a value of “”, which is an empty value as far as a string is concerned, but is still a value when compared to $null.
Let’s look at how to test for these conditions.
Test PowerShell variable for $null
Let’s open a fresh ISE session. Using the following code, we are declaring a variable $DemoString but not assigning it a value. We then immediately test it to see if it is $null.
We use $DemoString -eq $null:
PS C:\Users\aaron> $DemoString $DemoString -eq $null True
Test PowerShell variable for empty string value
Expanding on our original demo code, let’s now test the same variable to see if $null is equivalent to an empty string value, which is represented as “”:
PS C:\> $DemoString PS C:\> $DemoString -eq $null True PS C:\> $DemoString -eq "" False
You can see from this that $DemoString with no value assignment tests true for $null, but NOT for an empty string “”. To further confirm this, we can test $null against “” directly:
PS C:\> $null -eq "" False
This fails because even though the empty string value doesn’t seem like a true value, it is in fact a legitimate string type value.
Test PowerShell variable for either $null or empty string value
Now let’s look at how you might use this knowledge when scripting. We now know there are two distinct conditions that we need to potentially test for before attempting an operation on a variable.
In this example, we are going to use Get-CimInstance to return information about a specified Windows service. In this particular case, we are checking whether or not the variable holds an object. In the first command, we get WinRM, a valid service. In the second command we attempt to get FakeService, which doesn’t exist.
PS C:\> $Service = Get-CimInstance -ClassName Win32_Service -Filter "Name='WinRM'" $Service -eq $null False PS C:\> $Service = Get-CimInstance -ClassName Win32_Service -Filter "Name='FakeService'" $Service -eq $null True
You can see that $Service is NOT $null in the first command, but IS $null in the second command. Straightforward.
Now, let’s look at a service running on my computer, AMD External Events Utility. I know by looking at services.msc that there is no Description for this service. What I do not know is whether it will be a $null value or an empty string value, given that the property is a string.
I could perform two comparisons, combined with an -or:
PS C:\> $Service = Get-CimInstance -ClassName Win32_Service -Filter "Name='AMD External Events Utility'" $Service.Description -eq "" -or $Service.Description -eq $null True
This works, but you have to always remember to code for two comparisons, and it is twice as much work as a single comparison. Luckily, there is a .NET String method we can take advantage of directly called IsNullOrEmpty. To use this within PowerShell, we type [string]::IsNullOrEmpty($variable) to use the .NET class’ method:
PS C:\> $Service = Get-CimInstance -ClassName Win32_Service -Filter "Name='AMD External Events Utility'" [string]::IsNullOrEmpty($Service.Description) True
Add test for spaces value with IsNullorWhiteSpace
The last scenario you may want to test is your variable has a value, it isn’t null or an empty string, but the “value” only consists of spaces. For example, you may have a CSV file that the author accidentally entered a space in a column for which they didn’t intend to enter a value. In your script logic, you may test for a null or empty string update your parameters accordingly, but what if a value of white space would cause abnormal behavior too?
To test for this case we will use another .NET class String method [string]::IsNullOrWhiteSpace($variable). The advantage of this method compared to IsNullOrEmpty is that IsNullOrWhiteSpace will check for ALL THREE conditions we’ve discussed so far (null, empty string, or a string consisting of white space). So if you indeed want to check for all three of these cases, you can do so with one test:
PS C:\> $DemoString = $null [string]::IsNullOrWhiteSpace($DemoString) True PS C:\> $DemoString = "" [string]::IsNullOrWhiteSpace($DemoString) True PS C:\> $DemoString = " " [string]::IsNullOrWhiteSpace($DemoString) True
Understand your use case
I warn you, don’t jump right to using IsNullOrWhiteSpace! You need to understand the impact of having either a $null, empty string, or white space value in your data set. Any three of these may be an acceptable value, albeit not a very interesting one. Remember IsNullOrEmpty and IsNullOrWhiteSpace only return True or False, they do not tell you which condition was matched that the method is capable of testing. Make sure you are picking the appropriate set of tests for your use case.
Reference
- About Automatic Variables (description of $null) | docs.microsoft.com
- String.IsNullOrEmpty Method (String) | msdn.microsoft.com
- String.IsNullOrWhiteSpace Method (String) | msdn.microsoft.com
Krzysztof says
it is not PowerShell but .Net example
Taylor says
For most scenarios, I feel that it’s most concise in Powershell to simply use a variable (or expression) in an if-statement condition with no comparison operators, as it covers variables that do not exist and $null values, as well as empty strings. For example:
if ($x) {“Variable ‘x’ exists and is neither null nor contains an empty value”}
If you just want to know if a variable was never assigned a non-empty value, it’s this simple:
-not $x
db says
Exactly what I needed to know. Kudos, sir.
John Straffin says
The PowerShell examples are actually backwards. See https://github.com/PowerShell/PSScriptAnalyzer/blob/master/RuleDocumentation/PossibleIncorrectComparisonWithNull.md for more information. Proper PowerShell-based null-checks and empty-checks should start with the $null or “”.
Check out this string of examples:
PS C:\Users\me> $x = (“a”,””,”c”,”d”,””,$null,”g”)
PS C:\Users\me> $x -eq “”
<—the first ""
$x -eq $null ($x -eq “”).count
2
PS C:\Users\me> ($x -eq $null).count
1
PS C:\Users\me> “” -eq $x
False
PS C:\Users\me> $null -eq $x
False
PS C:\Users\me> $null -eq $x[2]
False
PS C:\Users\me> $null -eq $x[1]
False
PS C:\Users\me> $x[0]
a
PS C:\Users\me> $x[1]
PS C:\Users\me> “” -eq $x[0]
False
PS C:\Users\me> “” -eq $x[1]
True
PS C:\Users\me> $null -eq $x[1]
False
PS C:\Users\me> $null -eq $x[5]
True
John Straffin says
(Looks like HTML ate some of my comments. Oh well, you get the idea.)
Aaron Rothstein says
Thank you for pointing that out John, I learned something there!
thiyagi says
Nice one, thanks..:)