You need to prevent the implicit enumeration of your empty array in the (implicitly used) pipeline, the simplest solution to which is to wrap it in an aux., transitory array, which you can construct with the unary form of ,
, the array constructor operator:
$accessList = if ($condition) { , @() } else { $accessControl.AllowedItems }
PowerShell 7+ offers a way to bypass the problem, by using ?:
, the ternary conditional operator, which acts as an expression (see explanation below):
$accessList = $condition ? @() : $accessControl.AllowedItems
Background information:
The distinction is subtle:
In:
$accessList = @()
@()
is an expression and therefore assigned as-is.
In:
$accessList = if ($condition) { @() }
if ($condition) { @() }
is an entire statement, and as such its output (@()
) implicitly uses the pipeline, where an array is implicitly enumerated and its elements are sent to the pipeline; in the case of an empty array, there is nothing to enumerate, and therefore nothing is output ( which is technically represented as the [System.Management.Automation.Internal.AutomationNull]::Value
singleton).
Wrapping the array in an aux., transitory array as shown at the top makes the pipeline enumerate only that aux. array, so the wrapped array is output as a whole.
The same applies to outputs from commands, notably if you try to output an array as a whole from a script or function.
Generally, though, note that PowerShell commands are not expected to output collections as a whole and to instead enumerate them.
Also note that if two or more elements are enumerated in the pipeline and you assign the output to a variable, PowerShell implicitly collects them in an [object[]]
array, whereas a single element is assigned as-is (no array wrapper). See this answer for more information.