To complement Mathias R. Jessen's helpful answer, which explains the issue well:
An alternative to @(...)
is to type-constrain the result variable with [array]
placed to the left of the variable, in order to ensure that the collected result is always an array:
# Ensure that $arrayAfterUnique always contains an array.
[array] $arrayAfterUnique = 1, 1 | Select-Object -Unique
[array]
is in effect the same as [object[]]
, i.e., a regular PowerShell array.
If the output from the RHS command is a single value (scalar), that value is now automatically converted to a single-element array; with multiple output values, the [object[]]
array implicitly created by PowerShell for collecting the outputs is stored as-is.
Note: Type-constraining a variable means that future assignments too must be of the locked-in type or convertible to it; e.g., later execution of $arrayAfterUnique = 42
again converts integer 42
to a single-element array.
However, it is often not necessary to distinguish between scalars and arrays, because PowerShell allows you treat scalars like arrays, by given them a .Count
property with value 1
and allowing indexing with [0]
and [-1]
- see this answer for more information.
As for the input side:
On sending arrays to the pipeline, PowerShell enumerates them - that is, the elements are sent one by one to the command in the next pipeline segment.
Therefore, single-value input is effectively the same as single-element array input.
That is, the following two commands behave identically:
# In both cases, Select-Object receives single value '55'
'55' | Select-Object -Unique # single value
@('55') | Select-Object -Unique # single-element array
If you need to ensure that an array is sent as a whole to the pipeline, precede it with ,
(the array-construction operator)[1]:
# Send array 1, 2 as a whole to ForEach-Object
# Note the need for (...) to clarify precedence.
, (1, 2) | ForEach-Object { $_.GetType().Name } # -> 'Object[]'
# Less efficient, but conceptually clearer alternative:
Write-Output -NoEnumerate 1, 2
[1] This wraps the array in an auxiliary single-element helper array, and it is that helper array that PowerShell enumerates, therefore sending its one and only element - the original array - as-is through the pipeline.