Am I doing something stupid here?
I specify that a function takes a particular enum type as an argument:
PS> add-type -AssemblyName System.ServiceProcess
PS> function test([System.ServiceProcess.ServiceControllerStatus]$x) { Write-host $x $x.gettype() }
The type is most definitely in scope since I can access instances of it (and I imported the assembly manually):
PS> [System.ServiceProcess.ServiceControllerStatus]::Stopped
Stopped
Then when I try to pass the function an instance of said enum, it errors out:
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
It's quite happy coercing a string, though:
PS> test 'Stopped'
Stopped System.ServiceProcess.ServiceControllerStatus
What's going on?
You are running into a small gotcha regarding parsing modes. You can put parens around the argument and it will work:
test ([System.ServiceProcess.ServiceControllerStatus]::Stopped)
Alternatively, conversions from string to enum happen naturally, so you could write:
test Stopped
Here are a couple good links that discuss parsing modes:
You can pass an enum value as a string but you don't pass the typename as part of the argument e.g. this works just fine:
PS> test Stopped
Stopped System.ServiceProcess.ServiceControllerStatus
That said, when I'm calling .NET methods I prefer to use the fully qualified enum value instead of a string. That's because .NET methods tend to have multiple overloads and those that take strings can confuse PowerShell when to comes to picking the right overload.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With