PowerShell不能使用匹配的枚举类型?

时间:2014-09-08 20:39:45

标签: powershell types parameters enums

我在这里做些蠢事吗?

我指定一个函数将特定的枚举类型作为参数:

PS> add-type -AssemblyName System.ServiceProcess
PS> function test([System.ServiceProcess.ServiceControllerStatus]$x) { Write-host $x $x.gettype() }

该类型绝对是范围,因为我可以访问它的实例(并且我手动导入了程序集):

PS> [System.ServiceProcess.ServiceControllerStatus]::Stopped
Stopped

然后,当我尝试将函数传递给所述枚举的实例时,它会出错:

PS> test [System.ServiceProcess.ServiceControllerStatus]::Stopped
test : Cannot process argument transformation on parameter 'x'. Cannot convert value
"[System.ServiceProcess.ServiceControllerStatus]::Stopped" to type "System.ServiceProcess.ServiceControllerStatus".
Error: "Unable to match the identifier name [System.ServiceProcess.ServiceControllerStatus]::Stopped to a valid
enumerator name.  Specify one of the following enumerator names and try again: Stopped, StartPending, StopPending,
Running, ContinuePending, PausePending, Paused"
At line:1 char:6
+ test [System.ServiceProcess.ServiceControllerStatus]::Stopped
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [test], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,test

但是很高兴强迫一个字符串:

PS> test 'Stopped'
Stopped System.ServiceProcess.ServiceControllerStatus

发生了什么事?

(PowerShell错误消息太乱了。= /)

4 个答案:

答案 0 :(得分:9)

您正在遇到有关解析模式的小问题。你可以在论证周围加上一些parens,它会起作用:

test ([System.ServiceProcess.ServiceControllerStatus]::Stopped)

或者,从字符串到枚举的转换自然发生,因此您可以写:

test Stopped

以下是一些讨论解析模式的好链接:

http://technet.microsoft.com/en-us/library/hh847892.aspx http://rkeithhill.wordpress.com/2007/11/24/effective-powershell-item-10-understanding-powershell-parsing-modes/

答案 1 :(得分:2)

您可以将枚举值作为字符串传递,但不要将类型名称作为参数的一部分传递,例如这很好用:

PS> test Stopped
Stopped System.ServiceProcess.ServiceControllerStatus

也就是说,当我调用.NET方法时,我更喜欢使用完全限定的枚举值而不是字符串。这是因为.NET方法往往有多个重载,而那些采用字符串的方法可能会让PowerShell在选择正确的重载时感到困惑。

答案 2 :(得分:0)

显然,PowerShell认为我发送的是字符串,而不是枚举对象。如果引用完全限定名称,则会收到相同的错误消息:

PS> test '[System.ServiceProcess.ServiceControllerStatus]::Stopped'
test : Cannot process argument transformation on parameter 'x'. Cannot convert value
"[System.ServiceProcess.ServiceControllerStatus]::Stopped" to type "System.ServiceProcess.ServiceControllerStatus".
Error: "Unable to match the identifier name [System.ServiceProcess.ServiceControllerStatus]::Stopped to a valid
enumerator name.  Specify one of the following enumerator names and try again: Stopped, StartPending, StopPending,
Running, ContinuePending, PausePending, Paused"
At line:1 char:6
+ test '[System.ServiceProcess.ServiceControllerStatus]::Stopped'
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [test], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,test

将枚举放在括号中以强制PowerShell首先评估它可以解决问题:

PS> test ([System.ServiceProcess.ServiceControllerStatus]::Stopped)
Stopped System.ServiceProcess.ServiceControllerStatus

答案 3 :(得分:-1)

您未正确指定$x参数。它需要包含在param()表达式中。

function test
{
    param(
        [ServiceProcess.ServiceControllerStatus]
        $x
    ) 
    Write-host $x $x.gettype() 
}

另外,您可以省略任何类型名称的System.部分。