我想做这样的事情:
<statement> | <filter1> | <filter2> if <condition> | <filter3> | <filter4> | <filter5>
<statement> 的结果通过 <filter1> 运行,然后它们仅在满足 <condition> 时运行通过 <filter2>,然后通过其余过滤器,无论是否应用 <filter2>。这相当于:
if (<condition>) {
<statement> | <filter1> | <filter2> | <filter3> | <filter4> | <filter5>
} else {
<statement> | <filter1> | <filter3> | <filter4> | <filter5>
}
这在仅当调用某个开关时才将给定过滤器应用于结果集的函数中很有用。如果条件过滤器出现在长管道的早期,使用外部 if 块编写它会导致大量代码重复,尤其是在有多个条件过滤器的情况下。
这是一个例子。以下函数显示给定帐户在给定目录子树中的权限(例如Show-AccountPerms \\SERVERX\Marketing DOMAIN\jdoe
,给出用户 DOMAIN\jdoe 在 \SERVERX\Marketing 下的目录树中的权限报告)。
function Show-AccountPerms {
param (
[parameter(mandatory = $true)]$rootdir,
[parameter(mandatory = $true)]$account,
[switch]$files,
[switch]$inherited
)
gci -r $rootdir `
|where {$_.psiscontainer} `
|foreach {
$dir = $_.fullname
(get-acl $_.pspath).access `
| where {$_.isinherited -eq 'False'} `
|foreach {
if ($_.identityreference -eq $account) {
"{0,-25}{1,-35}{2}" -f $_.identityreference, $_.filesystemrights, $dir
}
}
}
}
默认情况下,它只显示显式权限(由| where {$_.isinherited -eq 'False'}
过滤器强制执行),并且仅在目录上(由|where {$_.psiscontainer}
过滤器强制执行)。
|where {$_.psiscontainer}
但是,如果调用 -files 开关,我想忽略,如果调用 -inherited 开关,我想忽略| where {$_.isinherited -eq 'False'}
。使用外部 if 块完成此操作将使代码翻两番,其中几乎 75% 将是重复。有没有办法让这些过滤器保持一致,但指示 powershell 只应用它们对应的开关是假的?
请注意,这只是一个示例,因此我对特定于此功能的任何解决方法不感兴趣。我正在寻找有关有条件管道的一般问题的答案,而不是如何完成此特定任务的解决方案。