← PowerShell course
3

Filtering & Shaping the Pipeline

25 min

Master Where-Object, Select-Object, Sort-Object, Measure-Object, and ForEach-Object to slice, sort, and summarise live system data.

By the end you can
  • Filter objects with Where-Object using both the scriptblock and simplified forms
  • Apply comparison operators (-eq, -ne, -gt, -like, -match) and combine them with -and / -or
  • Shape output with Select-Object (properties, -First/-Last, calculated columns)
  • Sort results with Sort-Object and summarise with Measure-Object
  • Iterate objects inline with ForEach-Object and the $_ automatic variable

The Pipeline Is a Conveyor Belt

When you run Get-Service PowerShell doesn't hand you a block of text — it hands you a stream of objects, one per service. Every cmdlet to the right of a pipe (|) receives those objects and can inspect, filter, or transform them.


Where-Object — Keep Only What You Need

Two forms, same result:

# Simplified form (one property, one operator)
Get-Service | Where-Object Status -eq 'Running'

# Scriptblock form (required for -and / -or or complex logic)
Get-Service | Where-Object { $_.Status -eq 'Running' -and $_.StartType -eq 'Automatic' }

$_ is the current object in the pipeline — think of it as "this one".

Comparison Operators

OperatorMeaning
-eq / -neequals / not equals
-gt / -ltgreater / less than
-ge / -legreater-or-equal / less-or-equal
-likewildcard match (*, ?)
-matchregex match

Combine with -and and -or inside a scriptblock:

Get-Process | Where-Object { $_.CPU -gt 10 -and $_.WorkingSet -gt 100MB }

Select-Object — Choose Your Columns

# Pick specific properties
Get-Service | Select-Object Name, Status, StartType

# First / last N objects
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5

# Calculated property
Get-Process | Select-Object Name, @{Name='MemMB'; Expression={ [math]::Round($_.WorkingSet / 1MB, 1) }}

The hashtable @{Name='...'; Expression={...}} lets you rename or compute a column on the fly.


Sort-Object

Get-Process | Sort-Object -Property CPU -Descending
Get-Service | Sort-Object DisplayName   # ascending by default

Measure-Object — Count and Aggregate

Get-Service | Where-Object Status -eq 'Running' | Measure-Object
# Count : 87

Get-Process | Measure-Object WorkingSet -Sum -Average

ForEach-Object — Act on Each in Turn

Get-Service | Where-Object Status -eq 'Stopped' | ForEach-Object {
    Write-Host "Stopped service: $($_.DisplayName)"
}

Use ForEach-Object when you need to do something for every object rather than just display it.