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 name4. Flow Control and Expansion
- Value expansion:
Select-Object -ExpandPropertysends 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 Stopor$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 -WhatIf8. 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.