Comma as a Unary Operator

I’m reading through Powershell in Action and this one spot in Chapter 5 makes my head hurt. I comprehend what’s happening here but I’d like some help on its usefulness and why it’s doing it.

$a = 1,(2,3)
$b = $a | foreach { $_ }

$b.length

So, $b.length is 3. Makes sense.

$a = 1,(2,3)
$b = $a | foreach { , $_ }

$b.length

Now $b.length is 2.

I understand what the 2 objects are because $b[0]; $b[1] -join "," shows this but I don’t really understand what the comma is doing in the second ForEach?
Is it basically saying, “Hey, take 1 as one object and (2,3) as it’s own object. Don’t separate them.”

Powershell pipeline “unrolls” collections as a convenience and (laughably for “consistency”) to users. The unary operator allows you to prevent powershell from doing just that. I think the examples could’ve been better, I’ll give it a go.

Compare the output from these two examples

(1,2,3) | ForEach-Object {
    Write-Host "The current pipeline object is $_"
}

The current pipeline object is 1
The current pipeline object is 2
The current pipeline object is 3
,(1,2,3) | ForEach-Object {
    Write-Host "The current pipeline object is $_"
}

The current pipeline object is 1 2 3

As you can see in the second example, the entire collection was sent as one object, preventing it from being unrolled. It is actually an array, the reason it shows with spaces instead of commas is due to the default output field separator being a space (which is stored in variable $ofs). You can see this in action like so

"$(1, 2, 3)"

1 2 3

Since the array was embedded in a string, powershell joins them together with the default OFS. You can change this, though this is rarely needed.

$ofs = '\-/'

"$(1, 2, 3)"

1\-/2\-/3

I’d say one of the more common uses I personally have for the unary operator is when I want to split some values but send all of the elements as one object.

,(-split 'Doug loves powershell') | ForEach-Object {
    [PSCustomObject]@{
        Person  = $_[0]
        Verb    = $_[1]
        Subject = $_[2]
    }
}

Person Verb  Subject   
------ ----  -------   
Doug   loves powershell
2 Likes

Thank you! This makes MUCH more sense. Especially when doing your last example without the unary operator.

The book example was just tough to wrap my head around.