Skip to content
AgileLogics
5 min read

The Pipeline

Prerequisites: Objects, not text

The pipeline (|) passes the objects output by one command to the next. Each command does one job; chained together, they do big ones.

$people = @(
  [pscustomobject]@{ Name = 'Ada';    City = 'London';   Age = 36 }
  [pscustomobject]@{ Name = 'Linus';  City = 'Helsinki'; Age = 28 }
  [pscustomobject]@{ Name = 'Grace';  City = 'New York'; Age = 45 }
  [pscustomobject]@{ Name = 'Alan';   City = 'London';   Age = 41 }
)

$people | Where-Object City -eq 'London' | Sort-Object Age | Select-Object Name, Age

Name Age
---- ---
Ada   36
Alan  41

Reading left to right:

  1. Start with four person objects.
  2. Where-Object keeps those whose City is London.
  3. Sort-Object sorts them by Age.
  4. Select-Object keeps just the Name and Age properties.

$_ — the current object

In script blocks ({ ... }) that run once per object, $_ (also written $PSItem) is the current object:

1..5 | ForEach-Object { $_ * $_ }
'apple', 'banana', 'cherry' | ForEach-Object { "$_ has $($_.Length) letters" }
1
4
9
16
25
apple has 5 letters
banana has 6 letters
cherry has 6 letters

Counting and summarizing

$orders = 120, 45, 300, 80

$orders | Measure-Object -Sum -Average -Maximum |
  Select-Object Count, Sum, Average, Maximum

Count     Sum Average Maximum
-----     --- ------- -------
    4 545.000 136.250 300.000

Grouping

'red', 'blue', 'red', 'green', 'red', 'blue' |
  Group-Object |
  Sort-Object Count -Descending |
  Select-Object Name, Count

Name  Count
----  -----
red       3
blue      2
green     1

Common mistakes

  • Piping to a formatting command (Format-Table) in the middle of a pipeline. Formatting produces display objects, not data — keep Format-* at the very end (next lessons).
  • A pipe at the start of a line: PowerShell needs the | at the end of the line to continue the pipeline onto the next line. (PowerShell 7 also accepts a leading | on the continuation line.)