在我正在编写的脚本的创建过程中,我遇到了一个我从未见过的管道快捷方式的使用。
例如:
$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-Object
和ForEach-Object
相似,但存在重要差异。- 更多信息请看答案
顺便说一句:即使在使用Where-Object
cmdlet时,也可以简化命令,即简化语法:
$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 }
}
})
更新:正如您自己所发现的那样,如果您坚持使用管道,您可以将-PipeLineVariable
与Write-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