Filter, sort and select

PowerShell · Essentials · 12 min

These five cmdlets answer most 'which ones, how many, the biggest' questions about any data.

Once data is objects, a handful of cmdlets do most of the work:

  • Where-Object filters: Where-Object { $_.Length -gt 1MB }. Inside the script block, $_ (or $PSItem) is the current object. For a single comparison the simplified form Where-Object Length -gt 1MB also works.
  • Sort-Object orders by one or more properties: Sort-Object Length -Descending.
  • Select-Object picks properties (Select-Object Name, Length), takes -First/-Last items, removes duplicates with -Unique, and -ExpandProperty Name returns the bare values instead of objects with one property.
  • Group-Object groups by a property and counts.
  • Measure-Object computes count, sum, average, minimum and maximum.

Calculated properties add or rename columns: @{ Name = 'KB'; Expression = { $_.Length / 1KB } }. Size suffixes KB, MB, GB are built-in numeric literals.

Filter left: when a cmdlet has its own filter parameter, such as Get-ChildItem -Filter *.log or Get-Process -Name pwsh, use it. The provider or API does the filtering before objects are created, which can be dramatically faster than Where-Object on large sets, especially against remote systems.

Example

$files = Get-ChildItem $PSHOME -File
$files | Where-Object { $_.Length -gt 1MB } | Measure-Object |
  Select-Object -ExpandProperty Count            # how many files > 1 MB
$files | Where-Object Extension -eq '.json' |
  Select-Object -First 2 -ExpandProperty Name    # simplified syntax
$files | Sort-Object Length -Descending | Select-Object -First 3 Name,
  @{ Name = 'KB'; Expression = { [math]::Round($_.Length / 1KB) } }
$files | Group-Object Extension | Sort-Object Count -Descending |
  Select-Object -First 3 Count, Name             # most common extensions
$files | Measure-Object Length -Sum -Maximum | Select-Object Count, Sum, Maximum
Get-ChildItem $PSHOME -Filter *.json             # filter left: provider does it

Remember

  • Where-Object filters, Sort-Object orders, Select-Object picks
  • $_ is the current object inside script blocks
  • Use a cmdlet's own -Filter or -Name parameter before Where-Object

Watch out for

  • Expecting Select-Object Name to return strings; it returns objects with a Name property. Use -ExpandProperty.

Check yourself

  1. Which command returns plain strings of process names?
  2. Why prefer `Get-ChildItem -Filter *.log` over piping to `Where-Object Name -like '*.log'`?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object

Filter, sort and select · PowerShell · Topolearn