发送到PowerShell的字符串参数不是真正的字符串吗?

时间:2010-08-19 17:02:10

标签: powershell

我对下面脚本的行为感到有点困惑:

Test.ps1:

param(
    [array]$Value = $(throw "Give me a value")
)

Write-Host $Value 
$Value | Get-Member -MemberType Method
$Value.ToUpper()

运行脚本:

PS C:\Temp> .\weird.ps1 test
TypeName: System.String
Name MemberType Definition
—- ———- ———-
…
ToUpper Method string ToUpper(), string ToUpper(System.Globalization.CultureInfo culture)
…
Method invocation failed because [System.Object[]] doesn’t contain a method named ‘ToUpper’.
At C:\Temp\weird.ps1:6 char:15
+ $Value.ToUpper <<<< ()
+ CategoryInfo : InvalidOperation: (ToUpper:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

为什么我会收到MethodNotFound异常? Get-Member清楚地说它是一个字符串。

3 个答案:

答案 0 :(得分:5)

这里发生的是在脚本中将变量$value键入Object[]。对Get-Member的调用有效,因为您将值传递给函数。因此,它不是看到数组,而是看到数组中确实键入String的值。这可以通过使用以下Get-Member调用来查看,而无需管道

Get-Member -MemberType Method -InputObject $value

这也是ToUpper正确失败的原因(这是一个不是String的数组)。

答案 1 :(得分:4)

当您在powershell中管道任何内容的集合时,它会“展开”并逐个发送到条形(管道)字符的右侧。这意味着数组的内容将被发送到get-member。 Get-member只接受发送给它的第一个项目,因此它会显示字符串的成员。您的参数类型为[array],因此参数binder将$ value设置为长度为1的数组,其中包含字符串“test”。

示例:

ps> @(1,"hello",3) | gm
... shows members of int32

ps> @("hello", 1, 3) | gm
... shows members of string

为了在管道时查看数组的成员,你应该将它包装在另一个数组中,因此它将成为展开的项目:

ps> ,@("hello", 1, 3) | gm
... shows members of array

前导逗号“,”创建一个包装数组。

-Oisin

答案 2 :(得分:2)

$ Value实际上是一个数组,因为这是你在param块中声明参数的方式。