Hi ,
got into a problem with DynamicParams,
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 ?
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
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.
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
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
PS C:\windows\system32>
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 ?
I have posted it in UserVoice.
Vote if you feel it as a deficiency .