DynamicParams with Mandatory parameters

This topic contains 6 replies, has 4 voices, and was last updated by  kvprasoon 6 days, 1 hour ago.

  • Author
    Posts
  • #84125

    kvprasoon
    Participant

    Hi ,

    got into a problem with DynamicParams,

      an example code
    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
    }
    
    }
    

    when I execute by mentioning -r and with the expected 'yes' value, Parameter 'r' is having the value in it in DynamicParam{} and if loop passes.

    test -r 'yes'

    when I execute without mentioning -r and giving the expected value 'yes' when prompted as its mandatory, Parameter 'r' is not having the value in it in DynamicParam{} and if loop fails.

    test

    I can see key 'r' in the $PSBoundParameters, but the value is empty,

    any idea ?

  • #84127

    Sam Boutros
    Participant

    I typically won't define 'r' in the Param() section uptop, I would only define it in the DynamicParam {} script block as in:

    function test-Dynamic1 {
        [CmdletBinding(ConfirmImpact='Low')]Param()
    
        DynamicParam  {
            $ParamAttrib = New-Object System.Management.Automation.ParameterAttribute
            $ParamAttrib.Mandatory  = $true
            $ParamAttrib.ParameterSetName  = '__AllParameterSets'  
            $RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
    
            #region Add r dynamic variable - Only change the next 2 lines for each additional dynamic parameter you add
            $varName = 'r'
            $varValues = (Get-ChildItem .\).FullName
            $AttribColl = New-Object  System.Collections.ObjectModel.Collection[System.Attribute]
            $AttribColl.Add($ParamAttrib)
            $AttribColl.Add((New-Object  System.Management.Automation.ValidateSetAttribute($varValues)))  
            $RuntimeParam  = New-Object System.Management.Automation.RuntimeDefinedParameter($varName, [string],$AttribColl)
            $RuntimeParamDic.Add($varName, $RuntimeParam)
            #endregion
    
            $RuntimeParamDic  
        }
    
        Process{
            "r: ($($PSBoundParameters.r))"
        }
    }
    

    Line 6 $ParamAttrib.Mandatory = $true is where you make 'r' mandatory.
    To add additional dynamic parameters you repeat the #region inside the DynamicParam{} script block. You typically would populate the $varName and $varValues only.
    Finally you don't refer to $r in the script, but instead you refer to $PSBoundParameters.r

  • #84167

    kvprasoon
    Participant

    You didn't get the problem here, I can make as much as DynamicParam I want, Problem is in accessing the variables declared in Param block inside the dynamicparam block if the variable in Praam block is not provided while calling the Function/Script, But asked for the value as it is defined as mandatory.

    This is same in case if I have 2 dynamicParams and accessing 1st param's value to take a decision within the DynamicParam block.

  • #84205

    postanote
    Participant

    Running your code snippet unchanged, and just let it prompt me, I get the below, so, unless I am missing the point. I am not getting empty value returns:

    test
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    r: yes

    Key Value
    — —–
    r yes

    When I use your code as you do, I get

    test -r 'yes'
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    t:

    test -r 'yes'
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    t: yes

    Key Value
    — —–
    r yes
    t yes

    Doing the same thing quoting the string, I get

    test
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    r: 'yes'

    Key Value
    — —–
    r 'yes'

    Removing the quotes from the string as you have it, I get

    test -r yes
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    t:

    test -r yes
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    t: $r

    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    t: $r

    Key Value
    — —–
    r yes
    t $r

  • #84206

    Pradeep Arora
    Participant

    Your line 16 reads

            $Param                      = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter('t', [String], $AttributeCollection)    
    

    It is looking for a parameter called "t" as per what am seeing. This is what I got, confusing to me:

    PS C:\windows\system32> test -r yes
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    t:
    test : Cannot bind argument to parameter 't' because it is an empty string.
    At line:1 char:1
    + test -r yes
    + ~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [test], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,test

    PS C:\windows\system32>

  • #84217

    kvprasoon
    Participant

    Hi Pradeep, what I have posted is a pseudo code.

    The actual problem here is the value of a Parameter (here it is 'r') from the Param() block is not bound or visible in the DynamicParam block.

    My question is , is it by design or Am I missing something else ?

  • #84245

    kvprasoon
    Participant

    I have posted it in UserVoice.

    Vote if you feel it as a deficiency .

You must be logged in to reply to this topic.