Skip to content

Pipeline

PowerShell's pipeline passes "objects" between commands rather than plain text, making data processing more robust and efficient.

1. Core Concepts

  • The pipe operator | passes output objects from the previous command one by one to the next command's "parameter binding" logic.
  • Binding methods:
    • ByValue: When the input object type matches the target parameter type, bind directly.
    • ByPropertyName: When the input object has a property with the same name as the parameter, bind it.
  • Common processors: Where-Object (filter), Select-Object (project/select columns), Sort-Object (sort), Group-Object (group), Measure-Object (aggregate).

2. Example: Top N Largest Processes

powershell
Get-Process |
  Sort-Object WorkingSet -Descending |
  Select-Object -First 5 Name, Id, @{n='MemMB';e={$_.WorkingSet/1MB -as [int]}}

3. ByPropertyName Example

powershell
# Export process list to CSV, then import and stop these processes
Get-Process | Select-Object Name | Export-Csv procs.csv -NoTypeInformation
Import-Csv procs.csv | Stop-Process  # Name property will bind to -Name parameter by property name

4. Flow Control and Expansion

  • Value expansion: Select-Object -ExpandProperty sends the property value itself into the pipeline
  • Connect multiple streams: Write-Output (success output), Write-Error (error logging), etc.
  • End aggregation: ForEach-Object -End { ... } performs summary when stream ends
powershell
1..10 | ForEach-Object -Begin { $sum=0 } -Process { $sum+=$_ } -End { $sum }

5. Performance Points

  • Try to place filtering (Where-Object) early in execution to reduce subsequent data volume.
  • Project necessary fields before large data sorting and deduplication.
  • Prefer using .Where()/.ForEach() extension methods (PowerShell 3+) to reduce script overhead:
powershell
$procs = Get-Process
$top = $procs.Where({ $_.WorkingSet -gt 300MB }, 'First', 10)
$names = $top.ForEach({ $_.ProcessName })

6. Errors and Interruption

  • Command failures don't terminate the pipeline by default, can force termination with -ErrorAction Stop or $ErrorActionPreference='Stop'.
  • Catch and continue:
powershell
Get-ChildItem -Recurse -ErrorAction SilentlyContinue |
  Where-Object { $_.Length -gt 1MB }

7. Common Patterns

  • Grouped aggregation report:
powershell
Get-ChildItem -File | Group-Object Extension |
  ForEach-Object {
    [pscustomobject]@{
      Ext = $_.Name
      Count = $_.Count
      SizeMB = ($_.Group | Measure-Object Length -Sum).Sum / 1MB
    }
  } | Sort-Object SizeMB -Desc
  • Conditional branch processing:
powershell
Get-Service |
  ForEach-Object {
    if ($_.Status -eq 'Running') { $_ }
  } | Stop-Service -WhatIf

8. Summary

  • Pipeline passing objects reduces the fragility of parsing/concatenating text.
  • Combining ByValue/ByPropertyName, choosing appropriate processors and extension methods, can write efficient and readable one-liner streaming scripts.

Content is for learning and research only.