u/Discuzting

This is NOT a XY problem!
On PowerShell 7+

Something I really like about pwsh is how easily we could get auto complete and input validation working.

function Test([Parameter(Mandatory)][ValidateSet('A', 'B', 'C')][String]$Option) {
    Write-Host $Option
}

Occasionally we will come across situations where input parameters has to be mapped to another value.

function Test([Parameter(Mandatory)][ValidateSet('A', 'B', 'C')][String]$Option) {
    Write-Host $(switch ($Option) {
        'A' { 'AAAAA' }
        'B' { 'BBBBB' }
        'C' { 'CCCCC' }
    })
}

If we want to avoid having two sources of truth, we could simply make use of IValidateSetValuesGenerator instead of string list:

$script:optionToConfig = @{
    'A' = 'AAAAA'
    'B' = 'BBBBB'
    'C' = 'CCCCC'
}
class TestValidateSetValuesGenerator : Management.Automation.IValidateSetValuesGenerator {
    [String[]] GetValidValues() { return $script:optionToConfig.Keys }
}

function Test([Parameter(Mandatory)][ValidateSet([TestValidateSetValuesGenerator])][String]$Option) {
    Write-Host $optionToConfig[$Option]
}

This works perfectly for functions in module scripts.

Trouble is, we cannot use the values generator approach when working with "top level" parameters of a script. This is because we cannot declare the generator above the parameter block, when the parameter block belongs to the script itself. Importing it from another module doesn't work neither.

Simply put, this works fine:

# In file `test.ps1`
param(
    [Parameter(Mandatory)][ValidateSet('A', 'B', 'C')][String]$Option
)

Write-Host $(switch ($Option) {
    'A' { 'AAAAA' }
    'B' { 'BBBBB' }
    'C' { 'CCCCC' }
})

But this doesn't work:

# In file `test.ps1`
$script:optionToConfig = @{
    'A' = 'AAAAA'
    'B' = 'BBBBB'
    'C' = 'CCCCC'
}
class TestValidateSetValuesGenerator : Management.Automation.IValidateSetValuesGenerator {
    [String[]] GetValidValues() { return $script:optionToConfig.Keys }
}
param(
    [Parameter(Mandatory)][ValidateSet([TestValidateSetValuesGenerator])][String]$Option
)

Write-Host $optionToConfig[$Option]

What better options do we have? Thanks for reading!

reddit.com
u/Discuzting — 26 days ago