Using a .NET Enumeration for PowerShell Parameter Validation
I recently ran into an issue where I wanted to use the values from a .NET enumeration as the default values for a parameter. That was easy enough:
1function Test-ConsoleColorValidation {
2 [CmdletBinding()]
3 param (
4 [ValidateNotNullOrEmpty()]
5 [string[]]$Color = [System.Enum]::GetValues([System.ConsoleColor])
6 )
7 $Color
8}
Although the previous code met my initial requirements, I decided that I also wanted the user to be able to tab expand the values and to validate the values based on the list of colors found in the enumeration without a requirement of having to hard code the values.
My first thought was to use the ValidateSet
parameter validation attribute, but it appears that
would require static values to be used for the valid colors. Next, I tried using a dynamic parameter
which added too much complexity for what I was trying to accomplish:
1function Test-ConsoleColorValidation {
2
3 [CmdletBinding()]
4 param ()
5
6 DynamicParam {
7 $Values = [System.Enum]::GetValues([System.ConsoleColor])
8 $DynParamDictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
9 $ParamAttributes = New-Object -TypeName System.Management.Automation.ParameterAttribute
10 $AttribColl = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute]
11 $AttribColl.Add($ParamAttributes)
12 $AttribColl.Add((New-Object -TypeName System.Management.Automation.ValidateSetAttribute($Values)))
13 $DynamicParameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter(
14 'Color',
15 [string[]],
16 $AttribColl
17 )
18 $DynParamDictionary.Add('Color', $DynamicParameter)
19 $DynParamDictionary
20 }
21
22 BEGIN {
23 if ($PSBoundParameters -notcontains 'Color') {
24 $PSBoundParameters.Add('Color', $Values)
25 }
26
27 $PSBoundParameters.GetEnumerator() |
28 ForEach-Object {New-Variable -Name $_.Key -Value $_.Value -ErrorAction SilentlyContinue}
29 }
30
31 PROCESS {
32 $Color
33 }
34}
I discovered that there's actually an easy way to accomplish this task while eliminating all that unnecessary complexity.
Simply use the class ([System.ConsoleColor] in this example) that describes the .NET enumeration as the parameter data type:
1function Test-ConsoleColorValidation {
2 [CmdletBinding()]
3 param (
4 [ValidateNotNullOrEmpty()]
5 [System.ConsoleColor[]]$Color = [System.Enum]::GetValues([System.ConsoleColor])
6 )
7 $Color
8}
The solution shown in the previous example meets all of my requirements.
It allows all colors in the enumeration to be used as the default value when the Color parameter is not specified without having to hard code the colors:
The valid values (colors in this scenario) which are part of the enumeration can be tab expanded and they show up in intellisense:
If an invalid color which is not a valid color as far as the enumeration is concerned happens to be specified, a meaningful error message is generated which provides the user of the function with a list of valid values:
Reference:
µ