任何人都可以向我解释我在使用|
将一个命令传递给另一个命令或使用$
来管道'时所看到的差异。它是一种不同的方式(抱歉不确定使用$
是否正在考虑使用管道)。
所以......这很有效:
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" }
这导致我收到此错误:
无法处理参数' Identity'的参数转换。无法转换" System.Collections.ArrayList"类型的值" System.Collections.ArrayList"键入" Microsoft.Exchange.Configuration.Tasks.GeneralMailboxOrMailUserIdParameter"。
当然,使用|
或$
是相同的,因为它将结果传递给下一个命令,还是我完全错了?
答案 0 :(得分:5)
我没有在这里进行交换shell测试,但我想我仍然可以解释基础知识并指出正确的方向。
管道|
用于将输出从一个命令重定向到另一个命令。 Powershell中的$
是定义其后面的字符序列是变量的字符(例如$Mailbox
作为正常变量的示例,或$_
作为变量的示例保存从前一个命令或表达式传出的数据。表达式1的示例是$(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
是{{1}的成员})。
如果你不清楚为什么有一个点和成员是什么,你应该稍微研究一下面向对象的编程,因为Powershell是面向对象的贯穿始终。
在您的第二个示例中,您只需保存$file
变量中Get-Mailbox
命令返回的所有内容。 $Mailbox
变量可用,只要您不删除它或保留其范围(在本例中为powershell会话)。实际上,您可以将变量用作多个命令的输入,而不会丢失其数据
使用管道时,第一个命令返回的数据只能用于管道后面的命令,之后它就消失了。
这可能是您感兴趣的差异。
至于你的实际问题: Powershell告诉你,它并没有期望被传递$Mailbox
类型的变量,这是System.Collections.ArrayList
返回的。 technet帮助不清楚Get-Mailbox
具体返回什么,但我强烈猜测它是一个Mailbox-Objects的ArrayList。您可以这样检查:
Get-Mailbox
要修复代码,您需要循环查看$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 $_ }
cmdlet循环遍历数组或列表,并分别处理每个项目
你的第一个例子到目前为止是因为Powershell has been made smarter about piped data a few versions ago(参见关于'成员枚举的段落')。它实际上正在传递传入的数据。
跟进链接:
The $_ variable in powershell
Powershell is an object oriented language
答案 1 :(得分:3)
很抱歉不得不这样说,但你完全错了。管道和变量是两个完全不同的东西。
管道(|
)将一个cmdlet的输出连接到另一个cmdlet的输入。列表输出一次处理一个项目,即第二个cmdlet分别接收每个列表项目。
如果收集变量($mailbox
)中的项列表并使用该变量调用cmdlet,则传递列表对象而不是单个列表项。仅当cmdlet参数接受数组输入时才有效。
答案 2 :(得分:2)
管道操作符|
我曾经将一个命令的输出流入另一个命令的输入。
美元符号c $
用于表示其后面的名称是变量,与cmdlet之间的管道数据无关。 where
cmdlet创建一个$_
变量,以便在其表达式中使用。