I want to do something like this:
<statement> | <filter1> | <filter2> if <condition> | <filter3> | <filter4> | <filter5>
The results of <statement> run through <filter1>, then they run through <filter2> only if <condition> is met, then through the remaining filters regardless of whether <filter2> was applied. This is the equivalent of:
if (<condition>) {
<statement> | <filter1> | <filter2> | <filter3> | <filter4> | <filter5>
} else {
<statement> | <filter1> | <filter3> | <filter4> | <filter5>
}
This would be useful in functions where a given filter is applied to the result set only if a certain switch was invoked. If the conditional filter occurs early in a long pipeline, writing it with an outer if-block results in a lot of repetition of code, especially if there is more than one conditional filter.
Here's an example. The following function shows the permissions a given account has in a given directory subtree (e.g. Show-AccountPerms \\SERVERX\Marketing DOMAIN\jdoe
gives a report of permissions that the user DOMAIN\jdoe has in the directory tree under \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
}
}
}
}
By default, it only shows explicit permissions (enforced by the | where {$_.isinherited -eq 'False'}
filter), and only on directories (enforced by the |where {$_.psiscontainer}
filter).
However, I want to ignore |where {$_.psiscontainer}
if the -files switch is invoked, and ignore | where {$_.isinherited -eq 'False'}
if the -inherited switch is invoked. Accomplishing this with outer if blocks would quadruple the code, and almost 75% of it would be repetition. Is there a way to keep these filters in-line but instruct powershell to only apply them of the corresponding switch is false?
Please note that this is just an example, so I'm not interested in any workarounds specific to this function. I'm looking for an answer to my general question regarding piping conditionally, not a solution for how to accomplish this particular task.