Skip to content

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 -WhatIf

8. 小结

  • 管道传递对象可减少解析/拼接文本的脆弱性。
  • 结合 ByValue/ByPropertyName、选择合适处理器与扩展方法,能写出高效可读的一行流式脚本。

本站内容仅供学习和研究使用。