PowerShell by default enumerates (unrolls) collections when outputting them to the pipeline: that is, instead of outputting the collection itself, its elements are output, one by one.
PowerShell collects all output objects from a pipeline in a flat array.
Therefore, even outputting multiple arrays creates a single, flat output array by default, which is the concatenation of these arrays.
A simpler example:
# Output 2 2-element arrays.
> 1..2 | % { @(1, 2) } | Measure-Object | % Count
4 # i.e., @(1, 2, 1, 2).Count
In order to produce nested arrays, you must suppress enumeration, which can be achieved in two ways:
- Simplest option: Wrap the output array in an aux. outer array so that enumerating the outer array yields the embedded one as a single output object:
# Use unary , to wrap the RHS in a single-element array.
> 1..2 | % { , @(1, 2) } | Measure-Object | % Count
2 # i.e., @(@(1, 2), @(1, 2)).Count
- Alternative, using
Write-Output -NoEnumerate (PSv4+):
> 1..2 | % { Write-Output -NoEnumerate @(1, 2) } | Measure-Object | % Count
2 # i.e., @(@(1, 2), @(1, 2)).Count
Note: While use of @(...) is not necessary to create array literals (as used above) - for literals, separating elements with , is sufficient - you still need @(...) to ensure that output from enclosed expressions or commands is treated as an array, in case only a single object happens to be output.