I have a GetDynamicParameters()
on cmdlet Get-DateSlain
that does something like this:
public object GetDynamicParameters()
{
List<string> houseList = {"Stark", "Lannister", "Tully"};
var attributes = new Collection<Attribute>
{
new ParameterAttribute
{
HelpMessage = "Enter a house name",
},
new ValidateSetAttribute(houseList.ToArray()),
};
if (!this.ContainsKey("House"))
{
this.runtimeParameters.Add("House", new RuntimeDefinedParameter("House", typeof(string), attributes));
}
}
And this works as expected - users can type Get-DateSlain -House
, and tab through the available houses. However, once a house is chosen, I want to be able to narrow down the results to characters in that house. Furthermore, if it's house 'Stark', I want to allow a -Wolf
parameter. So to implement (some value validity checks removed for brevity):
public object GetDynamicParameters()
{
if (this.runtimeParameters.ContainsKey("House"))
{
// We already have this key - no need to re-add. However, now we can add other parameters
var house = this.runtimeParameters["House"].Value.ToString();
if (house == "Stark")
{
List<string> characters = { "Ned", "Arya", "Rob" };
var attributes = new Collection<Attribute>
{
new ParameterAttribute
{
HelpMessage = "Enter a character name",
},
new ValidateSetAttribute(characters.ToArray()),
};
this.runtimeParameters.Add("Character", new RuntimeDefinedParameter("Character", typeof(string), attributes));
List<string> wolves = { "Shaggydog", "Snow", "Lady" };
var attributes = new Collection<Attribute>
{
new ParameterAttribute
{
HelpMessage = "Enter a wolf name",
},
new ValidateSetAttribute(wolves.ToArray()),
};
this.runtimeParameters.Add("Wolf", new RuntimeDefinedParameter("Wolf", typeof(string), attributes));
}
else if (house == "Lannister")
{
List<string> characters = { "Jaimie", "Cersei", "Tywin" };
// ...
}
// ...
return this.runtimeParameters;
}
List<string> houseList = {"Stark", "Lannister", "Tully"};
var attributes = new Collection<Attribute>
{
new ParameterAttribute
{
HelpMessage = "Enter a house name",
},
new ValidateSetAttribute(houseList.ToArray()),
};
this.runtimeParameters.Add("House", new RuntimeDefinedParameter("House", typeof(string), attributes));
}
This looks like it should work, but it doesn't. The GetDynamicParameters
function is only called once, and that is before a value is supplied to this.runtimeParameters["House"]
. Since it doesn't re-evaluate after that value is filled in, the additional field(s) are never added, and any logic in ProcessRecord
that relies on these fields will fail.
So - is there a way to have multiple dynamic parameters that rely on each other?