Powershell: Value bound to a mandatory param when prompted is not available in dynamicParam block

Created on 25 Nov 2017  路  2Comments  路  Source: PowerShell/PowerShell

From user voice
https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/32252068-mandatory-parameters-value-is-not-accessible-in-dy

Steps to reproduce

Function test{
    [Cmdletbinding()]
    Param(
        [Parameter(Mandatory)]
        $r
    )

DynamicParam {
    if( $r -eq 'Yes' ){

        $ParameterDictionary        = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
        $ParamAttribute             = New-Object -TypeName System.Management.Automation.ParameterAttribute
        $ParamAttribute.Mandatory   = $True
        $AttributeCollection        = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute]
        $AttributeCollection.Add( $ParamAttribute )        
        $Param                      = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter('t', [String], $AttributeCollection)    
        $ParameterDictionary.Add('t',$Param) | out-null
    return $ParameterDictionary

    }

}
Process{
    $PSBoundParameters
}

}

test

Expected behavior

test
1. will prompt for value for parameter r
2. should prompt for value for t if the desired value of r is given ('yes' is the value required here)

Actual behavior

test
will prompt for value for r , if value 'yes' is given, it will not prompt for value for parameter t

Environment data


Name                           Value
----                           -----
PSVersion                      6.0.0-rc
PSEdition                      Core
GitCommitId                    v6.0.0-rc
OS                             Microsoft Windows 10.0.17046
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Issue-Question WG-Engine

All 2 comments

Just to add some observations as to _when_ the DynamicParam {} block is executed (without knowing the design rationale behind it):

  • _after_ directly passed arguments have been bound
  • but _before_:

    • default values are assigned

    • missing mandatory parameters are prompted for.



      • curiously, it is invoked 4(!) times with -? and Get-Help



Therefore, your approach works if you invoke your function by directly passing 'Yes' to -r:

# Will define and prompt for -t
test -r Yes

What you're asking for would require delaying the evaluation of the DynamicParam {} block until after all _static_ mandatory parameter values have been prompted for.

Even if that change is feasible / will be made , making the _existence_ of the parameter conditional is problematic, however:
For instance, it won't show up at all with -?.

_Update_: It seems that the change is _not_ feasible, as implied by this comment: dynamic parameters are involved in parameter-set selection, so the final set of potential prompts won't be known until _after_ the dynamic parameters have been evaluated.

So, instead of the if ($r -eq 'Yes') conditional, perhaps use $ParamAttribute.Mandatory = $r -eq 'yes' to define the parameter itself unconditionally while making only its "mandatoriness" conditional - though even there I'm unsure as to whether conceptual problems can arise.

When I invoke GET-COMMAND | % PARAMETERS, I do not expect to be asked for values for mandatory parameters at all.

Was this page helpful?
0 / 5 - 0 ratings