You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在PowerShell的Where-Object中使用Splatting技术?

如何在PowerShell的Where-Object中批量处理通配符排除条件

好问题!确实splatting技术主要是用于简化参数传递的,没法直接在Where-Object的脚本块里用来拼接多个-notlike条件,但我们有几种更优雅的方式来处理你这种需要批量排除大量通配符模式的场景,不用写一堆重复的-and连接语句:

方法1:使用PowerShell 7+的-notany运算符(推荐)

如果你已经在用PowerShell 7或更高版本,-notany运算符可以完美解决这个问题——它会检查数组中没有任何一个元素满足后续脚本块的条件,刚好符合我们要排除所有匹配指定通配符的需求:

首先定义你的排除模式数组:

$excludePatterns = @(
    "Health*",
    "admin*",
    "service*",
    "test*"
    # 可以继续添加任意多的通配符模式
)

然后用Where-Object过滤:

$allUsers | Where-Object { $excludePatterns -notany { $_.UserPrincipalName -like $_ } }

这个逻辑很直白:只有当用户的UPN不匹配排除列表中的任何一个模式时,才会被保留下来。

方法2:兼容PowerShell 5.1的写法

如果还在使用PowerShell 5.1(比如Windows默认版本),可以用嵌套的Where-Object结合取反来实现同样的效果:

$excludePatterns = @("Health*", "admin*", "service*")

$allUsers | Where-Object {
    # 检查当前用户的UPN是否没有匹配任何排除模式
    -not ($excludePatterns | Where-Object { $_.UserPrincipalName -like $_ })
}

这里的逻辑是:先尝试在排除列表中找到与当前用户UPN匹配的模式,如果找到了(返回非空结果),取反后就会把这个用户过滤掉;如果没找到,就保留用户。

方法3:转成正则表达式一次性匹配

如果你的排除模式都是简单的通配符(只有*和?),还可以把所有通配符模式转换成正则表达式,然后用-notmatch一次性完成过滤,性能上可能更高效,尤其是当排除列表很长的时候:

$excludePatterns = @("Health*", "admin*", "service*")

# 把通配符转成正则:*替换成.*,?替换成.,然后用|连接所有模式
$regexPattern = $excludePatterns -replace '\*', '.*' -replace '\?', '.' -join '|'

$allUsers | Where-Object { $_.UserPrincipalName -notmatch $regexPattern }

这种方式相当于把所有排除模式合并成一个正则表达式,一次匹配就能判断是否需要排除用户。

总结一下,虽然splatting不能直接应用在Where-Object的条件判断里,但以上几种方法都能帮你优雅地处理批量通配符排除的需求,不用再写冗长的-and链式条件啦。

内容的提问来源于stack exchange,提问作者Ross Lyons

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:57:01