3

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?

8
  • Can't you just make $Target mandatory and drop the default value? It would make life so much simpler :P Commented Feb 27, 2013 at 14:43
  • @Graimer Well, I guess I could do that, but optional parameters with default values are so much nicer. Also, everybody can do simple :P Commented Feb 27, 2013 at 14:53
  • @poke 'but fails when the parameter is omitted' ... What's exactly fails? I'm trying your code and behave like expected.. maybe I miss something.. Have you set Set-PSDebug -strict ? Commented Feb 27, 2013 at 16:00
  • @C.B. Put the code into a .ps1 and call it without specifying any parameters. It will fail with an VariableIsUndefined error on the if. (PowerShell 3 btw). Commented Feb 27, 2013 at 16:02
  • @poke Ok, at the moment I'm on a v2 and I've no error, but if I do set-psdebug -stric I 've the error. Try to add set-psdebug -off maybe in v3 is ebavle by default... but IIRC is not. Commented Feb 27, 2013 at 16:05

1 Answer 1

5

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
}
Sign up to request clarification or add additional context in comments.

1 Comment

Simple but effective I guess ^^

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.