Your question boils down to this:
In PowerShell, how can I determine if a command or expression produced any output?
In almost all cases, the following is sufficient, as Ash suggests:
$Test = ... # ... represents any command or expression
if ($null -eq $Test) { 'no output' }
If you know that the command or expression - when it does produce output - only ever emits non-numeric and non-Boolean objects, you can simplify to the following, as Santiago Squarzon suggests, relying on PowerShell's implicit to-Boolean coercion logic, summarized in the bottom section of this answer:
$Test = ... # ... represents any command or expression
if (-not $Test) { 'no output' }
If you're dealing with an (unusual) command that outputs a collection (array) as a single object (as opposed to enumerating the collection and outputting each element separately, which is the normal pipeline behavior) and you want to treat an empty collection object as lack of output too:
$Test = ... # ... represents any command or expression
# Caveat: Due to a bug, only works robustly with
# Set-StrictMode turned off (the default)
# or Set-StrictMode -Version 1 (not higher).
if ($Test.Count -eq 0) { 'no output' }
Note that this works even with $null
output and a scalar output object (a single, non-collection object). In the interest of unified treatment of scalars and collections (arrays), PowerShell adds a .Count
property even to scalars that themselves do not have it, so that scalars can be treated as if they were a single-element collection, also with respect to indexing; e.g. (42).Count
is 1
, and (42)[0]
is 42
; however, note that $null.Count
is 0
. Such PowerShell engine-supplied type members are called intrinsic members.
Caveat: Due to a long-standing bug - reported in GitHub issue #2798 and still present as of PowerShell 7.2 - accessing the intrinsic .Count
property on objects that don't natively have it causes a statement-terminating error if Set-StrictMode
-Version 2
or higher is in effect.
However, the tests above do not allow you to distinguish between no output at all and a (single) $null
value, which requires the following approach - though do note that actual $null
output is unusual in PowerShell:[1]
$Test = ... # ... represents any command or expression
if ($null -eq $Test -and @($Test).Length -eq 0) { 'no output' }
This obscure test is necessary, because no output in PowerShell is represented by the [System.Management.Automation.Internal.AutomationNull]::Value]
singleton, which behaves like $null
in expression contexts, but not in enumeration contexts such as in a pipeline, including with @(...)
, the array-subexpression operator, which returns an empty array for [System.Management.Automation.Internal.AutomationNull]::Value]
(element count 0
) and a single-element array for $null
.
While making the distinction between $null
and [System.Management.Automation.Internal.AutomationNull]::Value
often isn't necessary, there are definitely cases when it is, given that their enumeration behavior differs. Being able to distinguish via a simple test such as $Test -is [AutomationNull]
is the subject of GitHub proposal #13465.
[1] Returning $null
from PowerShell commands (cmdlets, scripts, functions) is best avoided; instead, simply omit output commands. However, .NET API methods may still return $null
and object properties may contain $null
(even [string]
-typed ones, and even in PowerShell class
definitions - see GitHub issue #7294).