I was trying to understand how the constants $TRUE, $FALSE and $NULL work in Powershell, and how I should test for them or compare them with variables, respectively.
Being a Powershell newbie, I did some basic tests. While $TRUE and $FALSE behaved as expected, I was baffled by what I saw when I tried to assign another value to $NULL:
PS C:\Users\Administrator> $NULL=1
PS C:\Users\Administrator> $NULL="FOO"
PS C:\Users\Administrator> $NULL
PS C:\Users\Administrator>
$NULL should be constant or read-only, shouldn't it? So why can I assign another value to it without Powershell throwing an exception, and why is that assignment silently ignored?
In contrast, $FALSE behaves as expected:
PS C:\Users\Administrator> $FALSE=1
Cannot overwrite variable false because it is read-only or constant.
At line:1 char:1
+ $FALSE=1
+ ~~~~~~~~
+ CategoryInfo : WriteError: (false:String) [], SessionStateUnauthorizedAccessException
+ FullyQualifiedErrorId : VariableNotWritable
PS C:\Users\Administrator>
The primary reason that you can assign to
$null- even though as the representation of a null value it should be constant (as other PowerShell automatic variables such as$trueand$falseare, for instance) - is that it enables the following useful idiom for output suppression:That is,
$nullcan act like a regular read-write variable that you can assign to, but whatever you assign to it (a command's success output, from stream number1- seeabout_Redirection) is quietly discarded.Effectively,
$null = ...is the equivalent of>NUL(1>NUL) incmd.exeand>/dev/null(1>/dev/null) in POSIX-compatible shells such asbash.Note that in PowerShell you could alternatively use
... | Out-Nullor> $null, though the$null = ...idiom is faster thanOut-Null[1] and also signals the intent to discard the (success) output up front (unlike> $null). (There's also[void] (...), but it requires you to enclose the command in parentheses.) See this answer for more.However, you do need redirection if you also want to suppress other output streams (too); e.g.,
*> $nulldiscards the output from all streams.As for inspecting the properties of variables, including automatic ones, use the
Get-Variablecmdlet and pass it the name of the variable without the$sigil; e.g.,nullto inspect$null.Format-List *ensures that that all properties of the variable object (aSystem.Management.Automation.PSVariableinstance or an instance of a derived class) are listed, in list form.A constant variable such as
$falsewould showConstantas part of theOptionsproperty value.[1] Note: PowerShell [Core] v6+ has an optimization that makes
Out-Nullthe fastest solution if you discard an expression's value (e.g.,1..1e6 | Out-Nullvs. a command's (e.g.,Write-Output (1..1e6) | Out-Null), but note that suppressing command output is the much more common use case.