Filtering with Where-Object
Prerequisites: The pipeline
Where-Object keeps only the objects that match a condition.
Two syntaxes
$products = @(
[pscustomobject]@{ Name = 'Keyboard'; Category = 'Accessories'; Price = 89 }
[pscustomobject]@{ Name = 'USB-C Hub'; Category = 'Accessories'; Price = 35.5 }
[pscustomobject]@{ Name = 'Monitor'; Category = 'Displays'; Price = 249.99 }
[pscustomobject]@{ Name = 'Headphones'; Category = 'Audio'; Price = 199 }
)
# Simple syntax: one condition
$products | Where-Object Price -gt 100 | Select-Object -ExpandProperty Name
# Script block syntax: any expression, using $_
$products | Where-Object { $_.Category -eq 'Accessories' -and $_.Price -lt 50 } |
Select-Object -ExpandProperty Name
Monitor
Headphones
USB-C Hub
- The simple form (
Where-Object Property -operator Value) reads well for a single condition. - The script block form handles combined conditions with
-and,-or, and-not.
Filtering by pattern
$files = 'report.pdf', 'photo.jpg', 'notes.txt', 'report-old.pdf', 'logo.png'
$files | Where-Object { $_ -like '*.pdf' }
'---'
$files | Where-Object { $_ -match '^(photo|logo)\.' }
report.pdf
report-old.pdf
---
photo.jpg
logo.png
-like uses wildcards; -match uses regular expressions (both covered in
the Operators lesson).
Filter early — "filter left"
Many commands can filter themselves, which is much faster than getting
everything and then using Where-Object:
# illustrative
# Slower: gets every file, then filters
Get-ChildItem -Recurse | Where-Object Extension -eq '.log'
# Faster: the file system does the filtering
Get-ChildItem -Recurse -Filter *.log
Use a command's own parameters (-Filter, -Name, -Include) when they
exist, and Where-Object for everything else.
Practice
From the products above, list the names of products that are not in the Accessories category.
Show solution
$products = @(
[pscustomobject]@{ Name = 'Keyboard'; Category = 'Accessories' }
[pscustomobject]@{ Name = 'Monitor'; Category = 'Displays' }
[pscustomobject]@{ Name = 'Headphones'; Category = 'Audio' }
)
$products | Where-Object Category -ne 'Accessories' | Select-Object -ExpandProperty Name
Monitor
Headphones