Question

I have a PowerShell function that takes an optional parameter, validated using a ValidateSetAttribute, and based on that value it adds another dynamic parameter. However, in strict mode, when trying to access the parameter inside of the DynamicParam block, and I didn’t explicitely set said parameter, then I get an error that the variable was not defined.

Param(
    [Parameter()]
    [ValidateSet('A', 'B')]
    [string] $Target = 'A'
)
DynamicParam {
    if ($Target -eq 'B') { # <- Here it fails
        # Add new parameter here...
    }
}
end {
    Write-Host $Target
}

The script works when called with A or B as the first parameter, but fails when the parameter is omitted. Interestingly, if I remove either the ParameterAttribute or the ValidateSetAttribute from the parameter definition it works.

My current workaround is to access the variable using $PSBoundParameters and check if the parameter was set, like this:

if ($PSBoundParameters.ContainsKey('Target') -and $PSBoundParameters.Target -eq 'B') {
    # Add new parameter here...
}

While this works fine, it has one downside if I want to check for the value A instead: As A is the parameter’s default value it won’t be added to $PSBoundParameters when the parameter is omitted and the default value is applied. So I need to modify my check to explicitely check that:

if (-not $PSBoundParameters.ContainsKey('Target') -or $PSBoundParameters.Target -eq 'A')) {
    # Add new parameter here...
}

I don’t really like this solution as it will unnecessarily tie the dynamic parameter addition with the default values. Ideally, I would want to be able to change the default value without having to touch anything else. Is there any way to access the actual parameter value from within the DynamicParam block? Or is there at least a possibility to access the parameter definition and access the default value?

Was it helpful?

Solution

If you need run correctly in case PSDebug is running in strict mode ( set-psdebug -strict ), you can do something like this:

Param(
    [Parameter()]
    [ValidateSet('A', 'B')]
    [string] $Target = 'A'
)

DynamicParam {

    # Ensure $Target is defined
    try { [void]$Target }
    catch { $Target = [string]::Empty }

    if ($Target -eq 'B') {
        write-host "si si"
    }
}
end {
    Write-Host $Target
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top