关于管道变量和管道快捷方式的问题?



在我正在编写的脚本的创建过程中,我遇到了一个我从未见过的管道快捷方式的使用。

例如:

$acl | select -expandproperty Access | ? {$_.IdentityReference -eq "AD$Group"}
can be shortened to
$acl.Access.Where({$_.IdentityReference -eq "AD$Group"}) 

这是什么?acl美元。访问对我来说是有意义的,因为它只是一个属性引用,但我没有看到任何这样的。where()方法在这个对象上可用。因此,where({})似乎是"的某种管道快捷方式。Where-Object {}";我在哪里可以找到这种东西的文档?还有其他类似的吗?

第二个问题。我需要在我的结果中添加一个计算属性,并且在属性表达式中我还必须执行管道,所以我通常只从父管道引用$_,这在表达式语句中丢失了。

我可以通过在管道中使用-PipelineVariable来解决这个问题,但似乎这只在与cmdlet一起使用时有效,并且在使用变量启动管道时不可用(我经常这样做)。有办法解决这个问题吗?

如此:

$acl = Get-Acl -Path "AD:$dn"
$acl | select -expandproperty access -PipelineVariable AccessRight | ? {$_.IdentityReference -eq "AD$Group"} | select *, @{N='ObjectTypeName';E={($ADGuidMap.GetEnumerator() | ? {$_.Value -eq $AccessRight.ObjectType}).Name}}  

我真的希望能够做到这一点与快捷方式,我可以缩短我的在线我想做的任何地方。不幸的是,下面的操作不起作用,因为我不能在这个位置使用pipelinevariable。

$acl.Access.Where({$_.IdentityReference -eq "AD$Group"}) -PipeLineVariable AccessRight | select *, @{N='ObjectTypeName';E={($ADGuidMap.GetEnumerator() | ? {$_.Value -eq $AccessRight.ObjectType}).Name}} 

不能在cmdlet之外使用Pipeline变量一直困扰着我,所以我终于想问一下是否有某种方法可以解决这个问题。

对于第一个问题:

  • .Where().ForEach()方法内部成员,即PowerShell隐式地在任何类型的对象上提供的成员。

  • 虽然它们的功能与cmdlet对应体Where-ObjectForEach-Object相似,但存在重要差异。

    • 更多信息请看答案

顺便说一句:即使在使用Where-Objectcmdlet时,也可以简化命令,即简化语法:

$acl.Access | Where-Object IdentityReference -eq "AD$Group"

对于第二个问题:

因为.Where()方法不是cmdlet,所以不能与它一起使用通用的
-PipelineVariable参数。

考虑到.Access通常返回多个对象,使用-PipelineVariable的管道可以实现一个优雅的解决方案。

如果您确实想避免管道(操作符),您可以在中间(常规)变量的帮助下,像下面这样组合.Where().ForEach()方法:

$acl.Access.
Where({ $_.IdentityReference -eq "AD$Group" }).
ForEach({
$aclEntry = $_
Select-Object -InputObject $aclEntry -Property *, 
@{
N = 'ObjectTypeName'
E = { ($ADGuidMap.GetEnumerator().Where({ $_.Value -eq $aclEntry.ObjectType })).Name }
}
})
更新:

正如您自己所发现的那样,如果您坚持使用管道,您可以将-PipeLineVariableWrite-Output结合起来,以便在管道变量中捕获数组/集合的每个元素,以便稍后使用脚本块,如下面的(人造的)示例所示:

$array = 0..3
Write-Output $array -Pipeline arrayElement |
Where-Object { 0 -eq $_ % 2 } | # filter out odd numbers
ForEach-Object { $_ + 1 } | # add 1
ForEach-Object { "pipeline variable / `$_: $arrayElement / $_" }

输出,显示输入数组$array的每个元素在管道变量$arrayElement中被单独捕获:

pipeline variable / $_: 0 / 1
pipeline variable / $_: 2 / 3

最新更新