首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >前循环中的“不允许空管”

前循环中的“不允许空管”
EN

Stack Overflow用户
提问于 2017-08-24 20:22:25
回答 2查看 1.6K关注 0票数 0

我被要求修复一个同事今天写的PowerShell脚本的输出,当我试图从foreach循环中输出时,我注意到了一些奇怪的行为。当我在没有将可迭代对象$gpos输送到foreach的情况下运行循环时:

代码语言:javascript
代码运行次数:0
运行
复制
# This is the foreach loop in question
foreach ( $gpo in $gpos ) {
  [xml]$XML = Get-GPOReport -$gpo.DisplayName -ReportType Xml
  $admins = $XML.DocumentElement.Computer.ExtensionData.Extention.RestrictedGroups.Member

  # Not this one 
  $admins | foreach {
    [PSCustomObject]@{
      "GroupPolicy" = $gpo.DisplayName;
      "Permisisons" = $_.name.'#text';
    }
  }
} | Export-CSV -Path \path\to\file.csv -NoTypeInformation

我得到一个错误“一个空管道元素是不允许的”。

但是,如果我将$gpos对象输送到foreach循环中,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
$gpos | foreach {
  $gpo = $_
  # ...the rest of the code above
} | Export-CSV -Path \path\to\file.csv -NoTypeInformation

我能使用最后一根管子而不出问题。当语句以foreach循环开始,而不是迭代对象中的管道时,管道为什么不能工作?我自己很少使用第一种格式,所以我编写的代码没有遇到这个问题。我想不出这两种格式不应该工作的功能原因,因为如果管道输入为null,那么在本例中会抛出一个适当的异常。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-24 20:42:35

当语句以foreach循环开始,而不是迭代对象中的管道时,管道为什么不能工作?

因为一种语法是foreach语句,另一种语法是ForEach-Object命令的别名。这就像是Get-ChildItemif {} else {}之间的区别。

PowerShell的作者愚蠢地认为过度使用这个词是个好主意。从那以后,它就让语言的使用者感到困惑。

比较:

代码语言:javascript
代码运行次数:0
运行
复制
Get-Help about_Foreach -ShowWindow

Get-Help ForEach-Object -ShowWindow

前者甚至描述了PowerShell如何决定哪个是:

当Foreach出现在命令管道中时,Windows PowerShell使用foreach别名,它调用ForEach-Object命令。在命令管道中使用foreach别名时,不像使用Foreach语句那样包含($ in $)语法。这是因为管道中的优先命令提供了此信息。

底线是foreach不会将输出发送到管道中。你可以做得很好:

代码语言:javascript
代码运行次数:0
运行
复制
$x = foreach ($i in 1..10) { $i }

但这将失败:

代码语言:javascript
代码运行次数:0
运行
复制
foreach ($i in 1..10) { $i } | Where-Object { $_ -eq 2 }

正如MathiasR.Jesen在注释中所指出的,您可以将foreach语句包装在一个子表达式中,以使它与管道一起工作:

代码语言:javascript
代码运行次数:0
运行
复制
$(foreach ($i in 1..10) { $i }) | Where-Object { $_ -eq 2 }

ForEach-Object命令总是使用(并且需要)管道。

票数 1
EN

Stack Overflow用户

发布于 2017-08-24 20:35:06

一个是语言关键字foreach,另一个实际上是cmdlet ForEach-Object的别名。

语言关键字不能成为管道的一部分,这就是为什么您会得到这个异常。这也是为什么它们在不同的上下文中有不同的含义,如果foreach已经是管道的一部分,引擎就不会将它解析为关键字。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45870275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档