Powershell: Switch fails with null value

Created on 7 Aug 2019  路  6Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

$var = get-process | out-null
switch ($var) {
  $null { write-host NULL }
  default { write-host DEFAULT }
}

In my specific case, I assign $var to the output of a native command that, in some expected cases, doesn't return anything.
Note that explicitly assigning $var = $ null appears to be not the same thing and doesn't trigger the issue.

Expected behavior

Expecting the switch to be evaluated and the $null clause honored.

Actual behavior

The switch is entirely skipped.

Environment data

PSVersion                      6.2.2
PSEdition                      Core
GitCommitId                    6.2.2
OS                             Microsoft Windows 10.0.18362
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Question Resolution-Answered

All 6 comments

$var won't contain $null with the code you've given. In will continue PowerShell's "nothing" value - AutomationNull. This value indicates no value whatsoever, not even $null.

If Out-Null generated a $null, then this sequence would create output:

$items | Out-Null | % { 42 }

This is because $null is a perfectly valid pipeline value and would continue down the pipe.

Out-Null follows the idea of redirecting to /dev/null on Linux where no output is generated at all. A $null value is still a valid output value, however.

Even knowing this, I do not think there is a way to examine that with a switch statement. A switch statement iterates it's input, and will process arrays one item at a time. AutomationNull indicates to PowerShell that no iteration is to occur -- not in the pipeline, nor a foreach statement, etc., So the switch behaves the same.

Ok, now I'm confused.

I'm in my actual code I'm assigning to the output of some native command:
$var = az network dns record-set list [...] --query -otsv
that returns a list or nothing, if there's nothing to return.
I was assuming that in that case the variable got assigned to $null.

Actually, after that assignment, the following works fine:

    if ($var -eq $null) {
        Write-Host "something"
    } elseif ($var -eq $something) {
        Write-Verbose "somethingtoo"
    } else {
        Write-Host "somethingelse"
    }

So why is the first if actually working?
How am I supposed to actually check against the return of that native command?
Or better, it looks to me that switch is working as expected but the assignment is not.
I am, as a matter of fact assigning something that gets assigned to nothing instead of null?

An if statement doesn't iterate like a switch does, it's just a direct comparison as written.

AutomationNull is by definition equivalent to $null in a direct comparison, so that's why the if statement works.

It does appear the assignment results in truly nothing rather than $null, yeah. Unusual, really, most native utils output _something_.

Actually, the output (or lack there-of) of the command is quite normal. Simply the command has nothing to do/say or, in my specific case, the query result is empty.

If I get it right... the "AutomationNull" is equal to "unassigned"?
I find confusing that an assigment to something that is "nothing" results in an unassigned variable.
In what cases the output of a native command can result in a $null assignment?

If I get it right... the "AutomationNull" is equal to "unassigned"?

More like "no results". It acts a bit differently than an unassigned variable in some cases. It's a bit like how a SQL query could return a literal NULL value or just not find any matching results.

AutomationNull is like a mix between an empty collection (e.g. @() )and $null. A bit closer to an empty collection than $null.

@EPinci the output of a native command cannot result in a true $null assignment, because native commands only deal with text output. You can get "nothing", you can sometimes in odd cases get an empty string value ( [string]::Empty or '' ), or a string containing just whitespace.

Native commands don't deal with the CLR, so they don't have the ability to pass a $null value to another utility like PowerShell.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andschwa picture andschwa  路  3Comments

HumanEquivalentUnit picture HumanEquivalentUnit  路  3Comments

JohnLBevan picture JohnLBevan  路  3Comments

rkeithhill picture rkeithhill  路  3Comments

garegin16 picture garegin16  路  3Comments