在我正在编写的脚本的创建过程中,我偶然发现使用了一种我从未见过的管道快捷方式。
例如:
$acl | select -expandproperty Access | ? {$_.IdentityReference -eq "AD\$Group"}
can be shortened to
$acl.Access.Where({$_.IdentityReference -eq "AD\$Group"})
这是什么?$acl。Access对我来说是有意义的,因为它只是一个属性引用,但我没有看到任何这样的。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}}
我真的希望能够做到这一点的捷径,因为任何地方我可以缩短我的oneliner我想这样做。不幸的是,以下将无法工作,因为我不能使用pipelinevariable在这个位置。
$acl.Access.Where({$_.IdentityReference -eq "AD\$Group"}) -PipeLineVariable AccessRight | select *, @{N='ObjectTypeName';E={($ADGuidMap.GetEnumerator() | ? {$_.Value -eq $AccessRight.ObjectType}).Name}}
它总是困扰着我不能在cmdlet之外使用管道变量,所以我最终想问一下是否有某种方法可以解决这个问题。
1条答案
按热度按时间bwitn5fc1#
关于第一个问题:
.Where()
和.ForEach()
* 方法 * 是intrinsic members,即PowerShell隐式提供的可用于 * any * 类型对象的成员。Where-Object
和ForEach-Object
* 类似 *,但也有重要的区别。顺便说一句:即使在使用
Where-Object
cmdlet(即simplified syntax)时,您也可以简化命令:关于第二个问题:
因为
.Where()
* 方法 * 不是 * cmdlet *,所以不能使用公共-PipelineVariable
参数。考虑到
.Access
通常返回 * 多个 * 对象,使用-PipelineVariable
的管道可以实现一个优雅的解决方案。如果您确实希望避免管道(运算符),则可以在中间(常规)变量的帮助下组合
.Where()
和.ForEach()
方法,如下所示:更新:
正如您所发现的,如果您坚持使用管道,可以将
-PipeLineVariable
与Write-Output
结合使用,以便在数组/集合的每个元素流经管道时将其捕获到管道变量中,以供后面的脚本块使用,如以下(人为设计的)示例所示:输出,显示输入数组
$array
的每个元素都在管道变量$arrayElement
中单独捕获: