13

I'm writing a cmdlet (script) on powershell and I wanted to use eunm as one of the parameters. But I don't know where to put enum definition so that it would be visible for cmdlet parameters declaration.

For example, I have a parameters definition of the script like this

[cmdletbinding()]
param(
    [Parameter(Mandatory=$True)]
    [string]$Level
)

and an enum like this

enum LevelEnum { NC = 1; NML = 2; CS = 3 }

I can't replace [string] with [LevelEnum] in the parameter definition because script will fail to locate enum definition. And I can't put definition before cmdletbinding, it's not allowed. I know how to do it if that would've been a function, I know it can be solved using ValidateSet, but I need to have integer values correstonding to enum options.

[ValidateSet('NC','NML','CS')]

But the question is, can I do the same for a cmdlet?


Thanks to everyone. I ended up with a combination of defferent answers.

[cmdletbinding()]
param(
    [Parameter(Mandatory=$True)]
    [ValidateSet('NC','NML','CS')]
    [string]$Level
)
# Convert level from string to enum
enum PatchLevel { NC = 1; NML = 2; CS = 3 }
[PatchLevel]$l = $Level

# Use the numeric value
Write-Host $l.value__
1
  • 1
    Does this answer your question? Enum declaration Commented Jun 22, 2020 at 10:27

3 Answers 3

3

If this script needs to accept a custom enum, it means that you will be calling it from some other place, where enum definition already exists. And now you're trying to add the same definition again in a script. It would be good idea to push it out to a module as per @Alex_P suggestion so the definition resides in one place, but the downside is that Import-Module or #Requires won't import it, thus the need for using module clause.

But if you're willing to accept simpler and less secure solution, you could take advantage of the fact that any enum you define is derived from System.Enum. [System.Enum]$Level will accept only and all enums and if it's not LevelEnum the script will break, but still it filters most possible mistakes before the script execution and gives some information about parameter type.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks to everyone who replied. While most upvoted answers was most technically correct, but this answer actually made me to conclussion that my approach and my question was wrong. So I'll mark this one as accepted.
3
[cmdletbinding()]
param(
    [ArgumentCompleter({
        enum LevelEnum { NC = 1; NML = 2; CS = 3 }
        [LevelEnum].GetEnumValues()
    })]
    [ValidateScript({
        enum LevelEnum { NC = 1; NML = 2; CS = 3 }
        [LevelEnum]$_
    })]
    $Level
)

enum LevelEnum { NC = 1; NML = 2; CS = 3 }
[LevelEnum]$Level

This works, but I'm sure one will easily forget to edit all the enum definitions...

Comments

3

I would try something like this:

Below I created a plain PSM1 file with the LevelEnum definition.

enum LevelEnum{
  High
  Medium
  Low
}

Afterwards, I use using module with the path to the PSM1 file.

using module C:\Users\Path\To\Module\testmodule.psm1

function Get-Verb {
    [CmdletBinding()]
    param (
        [LevelEnum]$b
    )
    Write-Host $b
}

I used this microsoft documentation, About_Using and I also run version 7.0.2.

2 Comments

This does not work.
@noobie, my explanation works perfectly fine. What is the error you receive when following the instructions?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.