Objects and the Pipeline
Scope: the object model — Get-Member, filtering, sorting,
selecting, and formatting. The heart of PowerShell. All examples
were run with PowerShell 7.5.
Get-Member: what am I holding?
Get-Process | Get-Member
Get-Member lists an object's properties and methods. When a
command's output confuses you, pipe it here first. Narrow it:
Get-Process | Get-Member -MemberType Property
Where-Object: filtering
Get-Process | Where-Object { $_.CPU -gt 10 }
Where-Object keeps objects where the block is true; $_ is
the current object. (The ? alias exists — prefer the full
name in scripts.)
Select-Object: choosing properties
Get-Process | Select-Object Name, CPU, Id -First 5
Pick properties, take the first/last N, or compute new ones:
Get-ChildItem | Select-Object Name,
@{ Name = "KB"; Expression = { [math]::Round($_.Length / 1KB, 1) } }
The @{ Name=...; Expression=... } hashtable builds a
calculated property — derived columns on the fly.
Sort-Object and friends
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5
Get-ChildItem | Measure-Object Length -Sum
Get-Service | Group-Object Status
Measure-Object aggregates (count/sum/average),
Group-Object buckets by property value.
ForEach-Object: acting on each
Get-Service | Where-Object Status -eq "Stopped" |
ForEach-Object { Start-Service $_.Name }
(Where-Object Status -eq "Stopped" is the simplified syntax —
property, operator, value, no braces needed.)
Format vs data: the critical distinction
Get-Process | Format-Table Name, CPU -AutoSize # for HUMANS
Get-Process | Select-Object Name, CPU # for the PIPELINE
Format-* cmdlets destroy the objects — output is
formatting instructions, not data. Golden rule: Format-Table
(and friends) go last, only for screen display. Never pipe
from a Format-* command into anything expecting data.
Exporting: objects out to the world
Get-Process | Export-Csv processes.csv -NoTypeInformation
Get-Process | ConvertTo-Json | Out-File processes.json
Import-Csv processes.csv | Where-Object { $_.CPU -gt 10 }
Export-Csv / Import-Csv round-trip through spreadsheets;
ConvertTo-Json / ConvertFrom-Json through APIs and config.
-NoTypeInformation keeps the CSV clean.
The pipeline, summarized
Get-ChildItem -Recurse -File |
Where-Object { $_.Length -gt 1MB } |
Sort-Object Length -Descending |
Select-Object FullName,
@{ Name = "MB"; Expression = { [math]::Round($_.Length / 1MB, 1) } } |
Format-Table -AutoSize
Find big files, biggest first, as a readable table. Every stage
passes objects; only the final Format-Table is for eyes.
Check
- [ ] You reach for
Get-Memberwhen output confuses you - [ ] You can filter, sort, select, and compute a property
- [ ] You can explain why
Format-Tablemust come last
Next: Modules.