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?
The ValidateSetAttribute attribute specifies a set of possible values for a cmdlet parameter argument. This attribute can also be used by Windows PowerShell functions.
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.
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.
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.
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.
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