13

I have a function accepting an enum value as parameter. As an example, consider something like:

(PS) > function IsItFriday([System.DayOfWeek] $dayOfWeek) { 
    if($dayOfWeek -eq [System.DayOfWeek]::Friday) {
        "yes"
    } else {
        "no"
    } 
}

Now, if I invoke it like this, everything is fine:

(PS) > $m = [System.DayOfWeek]::Monday
(PS) > IsItFriday $m
no

But if I call the function passing directly the enum value, I get a rather cryptic error:

(PS) > IsItFriday [System.DayOfWeek]::Monday
IsItFriday : Cannot convert value "[System.DayOfWeek]::Monday" to type "System.DayOfWeek" 
due to invalid enumeration values. Specify one of the following enumeration values and 
try again. The possible enumeration values are "Sunday, Monday, Tuesday, Wednesday, 
Thursday, Friday, Saturday".
At line:1 char:11
+ IsItFriday  <<<< [System.DayOfWeek]::Monday

What's the difference between initializing a variable with the enum value and passing the enum value directly?

Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193

4 Answers4

20

It's a little bit unexpected - you need to wrap it in parenthesis so that the value is evaluated:

> IsItFriday ([System.DayOfWeek]::Monday)

also it is possible to pass only strings like this:

> IsItFriday Monday
no
> IsItFriday Friday
yes

PowerShell will convert it to the enum type. Handy, isn't it :)

stej
  • 28,745
  • 11
  • 71
  • 104
  • I knew about the implicit type conversion, handy indeed :) What I don't understand, anyway, is why there is this difference in the two cases... – Paolo Tedesco Jul 20 '10 at 12:07
  • 3
    The reason is that in `IsItFriday [System.DayOfWeek]::Monday` it is parsed like a string. The complete explanation can be found in PowerShell in Action by Bruce Payette. Its the same as `write-host get-date` vs. `write-host (get-date)`. – stej Jul 20 '10 at 12:29
  • When mentioning function calls and **wrapping parameters in parens**, note the possibility of a **parsing error**, as this post from a [previous stack overflow post](https://stackoverflow.com/questions/4988226/how-do-i-pass-multiple-parameters-into-a-function-in-powershell) explains (see 'accepted' answer). I have experienced the parsing error due to function parens, in certain situations, as late as PS 5.0 (apparently introduced in PS 2.0). – BentChainRing Oct 03 '19 at 18:43
10

To avoid the error put the enum value in parenthesis:

PS > IsItFriday ([System.DayOfWeek]::Monday)  
no

PS > IsItFriday ([System.DayOfWeek]::Friday)  
yes
Rui Jarimba
  • 11,166
  • 11
  • 56
  • 86
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
  • see comment note in post by @stej on caution of wrapping parameters in parens, in certain situations, resulting in a script parsing error. – BentChainRing Oct 03 '19 at 18:51
8

Yes, that is a rather confusing error message. I think you would understand better with an example:

Get-ChildItem -Path C:\

Notice there are no quotes around C:\ because, one, it implcitly gets converted to a string, and two, it is not necessary to enclose a path which does not contain spaces when you pass the path as a parameter to some callee.

So lets go back to your function, and change it slightly:

function IsItFriday($dayOfWeek) 
{
    $dayOfWeek.GetType()

    if ($dayOfWeek -eq [System.DayOfWeek]::Friday) 
    {
        "yes"
    } 
    else 
    {
        "no"
    }
}

IsItFriday [System.DayOkWeek]::Monday

...and the output:

IsPublic IsSerial Name                                     BaseType                                                                                        
-------- -------- ----                                     --------                                                                                        
True     True     String                                   System.Object                                                                                   
no

See what happened there? PowerShell thinks you are passing in a string instead of an enumeration value, so that's why you get Cannot convert value "[System.DayOfWeek]::Monday" because that is the literal string that gets passed in.

George Howarth
  • 2,767
  • 20
  • 18
5

Even handier is that strings will get converted to enum values if valid:

function IsItFriday([System.DayOfWeek] $dayOfWeek) {   
    if($dayOfWeek -eq [System.DayOfWeek]::Friday) {  
        "yes"  
    } else {  
        "no"  
    }   
}

PS 7> IsItFriday Monday
no
PS 8> IsItFriday Friday
yes
JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
  • That's worth knowing - I'd never have guessed it from the original post! – Francis Norton Feb 24 '14 at 11:19
  • Nice answer! While @GeorgeHowarth provides a good explanation of why it fails (which is technically what the question asked) yours is a useful supplement that explains a succinct way to make it succeed. – Michael Sorens Mar 23 '15 at 21:05