按条件筛选管道对象,保留满足条件的原对象,不改变对象结构。
Where-Object 对管道中的每个对象求值,输出条件为真的原对象,因此后续仍能访问完整属性和方法。别名是 where 和 ?。两种写法等价:脚本块 { $_.Status -eq 'Running' },或简化语法 -Property Status -eq 'Running';后者更短,但复杂条件仍要用脚本块。
管道:只从管道接收对象,输入是必需的;它不产生新对象,也不修改原对象。权限:本身不需要权限,能读到什么对象取决于上游命令。边界:Where-Object 筛“行”,Select-Object 选“列”,ForEach-Object 做转换;需要按属性排序用 Sort-Object。
版本:5.1 已支持简化语法、$_ 和 .Where() 方法;7.x 行为基本一致。跨版本脚本避免依赖 7.x 才有的运算符组合,复杂条件优先显式脚本块。
# 1. 按内存阈值筛选进程,保留完整 Process 对象
PS C:\> Get-Process | Where-Object { $_.WorkingSet64 -gt 500MB } | Select-Object Name, Id
# 2. 简化语法筛服务状态,适合单条件
PS C:\> Get-Service | Where-Object Status -eq 'Stopped' | Select-Object Name, StartType
# 3. 组合时间与大小条件,筛出陈旧且非空日志
PS C:\> Get-ChildItem C:\Logs -File | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) -and $_.Length -gt 0 }
# 4. 用通配符匹配进程名,注意与 -contains 的区别
PS C:\> Get-Process | Where-Object Name -like 'chrome*' | Measure-Object
# 5. 用正则筛选目录名,验证命名规范
PS C:\> Get-ChildItem C:\Apps -Directory | Where-Object { $_.Name -match '^test-' }
# 6. 方法语法,适合对已加载集合做链式筛选
PS C:\> $files = Get-ChildItem C:\Data -File; $files.Where({ $_.Length -eq 0 })
$_.Prop -eq $null 在属性是数组时会做元素筛选,结果仍可能为真;判空写成 $null -eq $_.Prop。0、空字符串、$null、空数组为假,非空字符串和集合为真;不要返回计数当布尔值。$null 并静默过滤掉全部对象;用 Set-StrictMode -Version Latest 暴露拼写问题。-contains 判断集合是否包含某元素,-like 做通配符匹配,-match 做正则匹配;混用会得到相反结果。Select-Object 丢掉属性再筛选;格式化对象(Format-Table 之后)也可能丢失属性。Where-Object 对大集合逐对象执行脚本块,性能不如上游命令自带的 -Filter;文件筛选优先用提供程序参数。$null。ForEach-Object — 对筛选后的对象做转换或副作用操作。Select-Object — 选择属性、计算列和前后 N 条。Sort-Object — 对筛选结果排序。Select-String — 在文本内容上搜索,而不是对象属性。合上页面,先回答,再展开对照。
Where-Object 会修改原对象或只返回副本吗?Where-Object { $_.Count } 在计数为 0 时会过滤掉对象?0 被视为假;应显式比较,如 $_.Count -gt 0。$null,条件为假,对象被静默过滤;用严格模式可暴露问题。
小程序版
微信扫码,随时查命令