Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use a constant in the ValidateSet attribute of a PowerShell function parameter?

Tags:

powershell

I am using the ValidateSet attribute on one of my PowerShell function parameters like so:

[ValidateSet('Development','Test','Production')]
[string]$Context

I have repeated this is many places throughout a scripting project. Can these literal strings be replaced with a constant?

like image 647
Matthew MacFarland Avatar asked Apr 15 '16 20:04

Matthew MacFarland


People also ask

What is ValidateSet in PowerShell?

The ValidateSetAttribute attribute specifies a set of possible values for a cmdlet parameter argument. This attribute can also be used by Windows PowerShell functions.

What is param () in PowerShell?

Parameters can be created for scripts and functions and are always enclosed in a param block defined with the param keyword, followed by opening and closing parentheses. param() Inside of that param block contains one or more parameters defined by -- at their most basic -- a single variable as shown below.

Is ValidateSet case sensitive?

By default, the ValidateSet attribute is case insensitive. This means that it will allow any string granted it's in the allowed list with any capitalization scheme.


2 Answers

Adding this to help others searching for a similar solution. I was looking for a way to validate parameters against the keys of a global hash table. This is what I ended up doing:

$global:MyHash = @{
    "anyitem"  = @{"name" = "somename1"; "count" = 42 };
    "someitem" = @{"name" = "another name"; "count" = 1337 };
}

function Test-Hash
{
    param
    (
        [Parameter(mandatory = $true)] [ValidateScript( { $_ -in $global:MyHash.Keys } )] [string[]] $items
    )
}

Test-Hash -items anyitem, someitem

I ended up replacing ValidateSet with ValidateScript as I realized (as mentioned in this thread as well) that the code block in ValidateSet does not work at all. Instead validating against the keys of a hash table one could easily use something like

$validParams = @('opt1', 'opt2')

and in the ValidateScript codeblock

{ $_ -in $validParams }

This is basically what I assume should answer the question.

like image 198
Aileron79 Avatar answered Oct 04 '22 08:10

Aileron79


No, it has to be a literal or a scriptblock. The scriptblock option seems pointless since it seems to use the literal (string) value of the scriptblock instead of executing it.

So effectively, from my testing, you must use literals.

If you use a dynamic parameter instead you could achieve this, but that's way overkill just to be DRY.

If you try to use a variable, it won't work (and ISE will give you the red squiggly). The help text erroneously says it must be a constant, but it means literal.

I created a constant with:

Set-Variable -Option Constant

And it still does not work.

like image 21
briantist Avatar answered Oct 04 '22 09:10

briantist