Pipeline(管道)
PowerShell 的管道在命令之间传递“对象”而非纯文本,使数据处理更稳健高效。
1. 核心概念
- 管道符
|将上一个命令的输出对象逐个传递给下一个命令的“参数绑定”逻辑。 - 绑定方式:
- ByValue(按值):输入对象类型与目标参数类型匹配时直接绑定。
- ByPropertyName(按属性名):输入对象拥有与参数同名的属性时绑定。
- 常见处理器:
Where-Object(筛选)、Select-Object(投影/选择列)、Sort-Object(排序)、Group-Object(分组)、Measure-Object(聚合)。
2. 示例:Top N 大进程
powershell
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 5 Name, Id, @{n='MemMB';e={$_.WorkingSet/1MB -as [int]}}3. ByPropertyName 示例
powershell
# 导出进程列表到 CSV,再导入并停止这些进程
Get-Process | Select-Object Name | Export-Csv procs.csv -NoTypeInformation
Import-Csv procs.csv | Stop-Process # Name 属性将按属性名绑定到 -Name 参数4. 流控制与展开
- 值展开:
Select-Object -ExpandProperty把属性值本身送入管道 - 连接多个流:
Write-Output(成功输出)、Write-Error(错误记录)等 - 结束聚合:
ForEach-Object -End { ... }在流结束时做汇总
powershell
1..10 | ForEach-Object -Begin { $sum=0 } -Process { $sum+=$_ } -End { $sum }5. 性能要点
- 尽量让过滤(Where-Object)靠前执行,减少后续数据量。
- 大数据排序与去重前先投影必要字段。
- 优先使用 .Where()/.ForEach() 扩展方法(PowerShell 3+)以减少脚本开销:
powershell
$procs = Get-Process
$top = $procs.Where({ $_.WorkingSet -gt 300MB }, 'First', 10)
$names = $top.ForEach({ $_.ProcessName })6. 错误与中断
- 命令失败默认不终止流水线,可通过
-ErrorAction Stop或$ErrorActionPreference='Stop'强制终止。 - 捕获并继续:
powershell
Get-ChildItem -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.Length -gt 1MB }7. 常见模式
- 分组聚合报告:
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- 条件分支处理:
powershell
Get-Service |
ForEach-Object {
if ($_.Status -eq 'Running') { $_ }
} | Stop-Service -WhatIf8. 小结
- 管道传递对象可减少解析/拼接文本的脆弱性。
- 结合 ByValue/ByPropertyName、选择合适处理器与扩展方法,能写出高效可读的一行流式脚本。