PowerShell 第11章:过滤和比较(下)

发布于:2025-08-17 ⋅ 阅读:(15) ⋅ 点赞:(0)

PowerShell 第11章:过滤和比较(下)


Where-Object、迭代命令行模型、常见坑位与练习

目标:把比较运算符真正“嵌”进管道,用 Where-Object 写出可读、可维护、性能可控的过滤命令;掌握迭代式构建管道的方法。


1️⃣ Where-Object:万能过滤器

1.1 标准语法(推荐记忆)

Get-Service | Where-Object { $_.Status -eq 'Running' }
# 读作:Where(对象的)Status 等于 Running
  • $_:管道占位符,一次只表示当前处理的那个对象
  • { ... }FilterScript,返回 $true/$false 即可。

1.2 v3 简写(了解)

Get-Service | Where Status -eq 'Running'

简写适合单条件;多条件、多行或含 $_ 的表达式,请用标准语法,可读性远好于堆叠简写。

1.3 多条件示例

# 同时筛选:正在运行 && 启动类型为手动
Get-Service | Where-Object { 
  $_.Status -eq 'Running' -and $_.StartType -eq 'Manual'
}

2️⃣ 迭代命令行模型(PSICLM):把复杂需求拆成 5 步

思想:不要企图一次写完终极命令,先跑通最小子问题,再“向上箭头”叠加。

需求:统计“除 PowerShell 进程外,虚拟内存(VM)占用最高的 10 个进程”的 VM 总和。
拆解 & 叠加命令:

# 1. 取进程
Get-Process

# 2. 排除 PowerShell 本体
Get-Process | Where-Object { $_.Name -notlike 'powershell*' }

# 3. 按 VM 排序(降序)
... | Sort-Object VM -Descending

# 4. 只要 Top 10
... | Select-Object -First 10

# 5. 求 VM 总和(Measure-Object)
... | Measure-Object -Property VM -Sum

随时按 ↑ 找回上一条命令小步修改;每一步都要看输出,确保在正确轨道上。


3️⃣ $_ 到底什么时候能用?

  • 只能在支持 FilterScript 的场合使用(如 Where-ObjectForEach-Object 等)。

  • 括号里的子管道也会产生自己的 $_ 作用域,务必分清:

    Get-Service -ComputerName (
      Get-Content .\names.txt |
      Where-Object { $_ -notlike '*dc' }  # 这里的 $_ 是“字符串(计算机名)”
    ) |
    Where-Object { $_.Status -eq 'Running' }   # 这里的 $_ 是“服务对象”
    

4️⃣ 远程/性能意识:把过滤“推到数据源”

  • 先过滤后传输永远更省:

    • AD:用 -Filter 把对象数量压到最少;
    • 远程:考虑用远程会话在目标机执行 Where-Object(第13章见)。
  • 避免在本地装载海量对象再过滤,尤其跨网络时。


5️⃣ 常见坑位 & 规避

  1. Where-Object 当第一选择

    • ✅ 优先考虑左过滤:能 -Filter 就别 Where
  2. 混淆“列头名”和“属性名”

    • Get-Member(或 Format-List *)查真实属性名。
    • 例:Get-Process 的列头 “PM(K)” 实际属性是 PM
  3. 在不支持的上下文使用 $_

    • 只在 Where-Object {}ForEach-Object {} 等能识别它的地方用。
  4. 括号子管道的作用域

    • 括号里的 $_ 与外层 $_ 不是同一个,分清对象类型。

6️⃣ 经典实战清单(带答案思路)

均来自本章练习,方便你检验掌握度。

  1. 物理网卡列表(Windows 8+/2012+)

    Import-Module NetAdapter
    Get-NetAdapter -Physical
    
  2. DNS 缓存中的 A / AAAA 记录

    Import-Module DnsClient
    Get-DnsClientCache -Type A,AAAA
    
  3. System32 下 > 5MB 的 EXE

    Get-ChildItem C:\Windows\System32\*.exe | Where-Object { $_.Length -gt 5MB }
    
  4. 仅列“安全更新”的补丁

    Get-HotFix -Description 'Security Update'
    
  5. 名为 Conhost 或 Svchost 且“运行中”的进程

    Get-Process -Name conhost, svchost | Where-Object { $_.Responding }
    # 或
    Get-Process | Where-Object { $_.Name -in @('conhost','svchost') -and $_.Responding }
    

7️⃣ 快速对照卡(可打印)

  • 优先-Filter > Where-Object
  • 位置:过滤越靠左越好、越靠近数据源越好
  • 匹配-like(通配符)/ -match(正则)
  • 大小写:默认不敏感,敏感用 -c*
  • 布尔-and / -or / -not
  • 属性名:不信列头名,Get-Member

网站公告

今日签到

点亮在社区的每一天
去签到