【问题标题】:Differences between | and $之间的差异|和 $
【发布时间】:2016-04-27 11:23:42
【问题描述】:

谁能向我解释我在使用| 将一个命令传递给另一个命令或使用$ 以不同方式“传递”它时看到的差异(抱歉,不确定是否使用$实际上正在考虑管道)。

所以……这行得通:

Get-Mailbox -ResultSize Unlimited | 
    where { $_.RecipientTypeDetails.tostring() -eq "SharedMailbox" } | 
    Get-MailboxPermission

这很棒,但是因为我想在上面不起作用的 Get-MailboxPermission 之后放置另一个 where 命令,然后我尝试使用它:

$Mailbox = Get-Mailbox -ResultSize Unlimited | 
           where { $_.RecipientTypeDetails.tostring() -eq "SharedMailbox" }

Get-MailboxStatistics -Identity $Mailbox |
    where { $_.IsInherited.tostring() -eq "False" }

这导致我收到此错误:

无法处理参数“身份”的参数转换。无法将“System.Collections.ArrayList”类型的“System.Collections.ArrayList”值转换为“Microsoft.Exchange.Configuration.Tasks.GeneralMailboxOrMailUserIdParameter”类型。

当然使用|$ 是一样的,因为它将结果传递给下一个命令,还是我完全错了?

【问题讨论】:

    标签: powershell pipe exchange-server


    【解决方案1】:

    我这里没有要测试的交换外壳,但我想我仍然可以解释基础知识并为您指明正确的方向。

    管道| 用于将输出从一个命令重定向到另一个命令。 Powershell 中的$ 是定义其后面的字符序列是一个变量的字符(例如,$Mailbox 作为普通变量的示例或$_ 作为保存已通过管道传输的数据的变量的示例通过上一个命令)或表达式。表达式之一的示例是 $(4+5)
    或者在一个更常用的例子中:

    PS C:\Users\Administrator> $file = (get-childitem)[0]
    PS C:\Users\Administrator> write-output "The fullname of $file is $($file.fullname)"
    The fullname of .ssh is C:\Users\Administrator\.ssh
    

    在该示例中,实际上需要使用表达式,因为字符串内的变量检测无法将点识别为变量和变量成员之间的分隔符(fullname$file 的成员)。
    如果你不清楚为什么有一个点以及成员是什么,你可能应该研究一下面向对象编程,因为 Powershell 是彻头彻尾的面向对象的。

    在您的第二个示例中,您只需将 Get-Mailbox 命令返回的所有内容保存在 $Mailbox 变量中。 $Mailbox 变量是可用的,只要您不删除它或离开其范围(在本例中为 powershell 会话)。您实际上可以将该变量用作多个命令的输入,而不会丢失其数据。
    使用管道时,您的第一个命令返回的数据只能被管道后面的命令访问,之后它就消失了。
    这可能就是您感兴趣的差异。

    至于您的实际问题: Powershell 告诉您它不希望收到System.Collections.ArrayList 类型的变量,这是Get-Mailbox 返回的。 technet 的帮助尚不清楚 Get-Mailbox 具体返回什么,但我强烈猜测它是邮箱对象的 ArrayList。你可以这样检查:

    $Mailbox.GetType()
    $Mailbox[0].GetType() # gets the type of the first object in $Mailbox
    

    要修复您的代码,您需要遍历Get-Mailbox 返回的内容。试试这个:

    $Mailboxes = Get-Mailbox -ResultSize Unlimited | where { $_.RecipientTypeDetails.tostring() -eq "SharedMailbox" }
    $Mailboxes | ForEach-Object { Get-MailboxStatistics -Identity $_ }
    

    ForEach-Object cmdlet 循环遍历数组或列表并单独处理每个项目。
    到目前为止,您的第一个示例有效,因为Powershell has been made smarter about piped data a few versions ago (请参阅有关“成员枚举”的段落)。它实际上是对传入的数据进行 ForEach-ing。

    后续链接:
    The $_ variable in powershell
    Powershell is an object oriented language

    【讨论】:

    • (天哪,这么多信息再次出现在我的脑海中 - 很长一段时间没有使用 Powershell。我现在将停止尝试改进我的答案 - 如果有不清楚的地方请告诉我: ))
    • 感谢您提供如此详细的答案,所有答案都非常有帮助,但这确实解决了问题,我重新编写了保存为 .ps1 的脚本,它运行良好。
    【解决方案2】:

    很抱歉不得不这么说,但你完全错了。管道和变量是两个完全不同的东西。

    管道 (|) 将一个 cmdlet 的输出连接到另一个 cmdlet 的输入。列表输出一次处理一项,即第二个 cmdlet 分别接收每个列表项。

    如果您在变量 ($mailbox) 中收集项目列表并使用该变量调用 cmdlet,则您传递的是列表对象而不是单个列表项。仅当 cmdlet 参数接受数组输入时才有效。

    【讨论】:

      【解决方案3】:

      管道运算符| 我曾经将一个命令的输出流到另一个命令的输入中。

      美元符号$ 用于表示其后面的名称是一个变量,与cmdlet 之间的管道数据无关。 where cmdlet 创建一个 $_ 变量以在其表达式中使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-13
        • 2010-10-19
        • 2020-09-15
        • 2014-06-30
        • 2011-11-16
        • 2011-05-08
        • 2010-11-23
        相关资源
        最近更新 更多