This is a barebones version of a function I am working on:
function Get-Firefox{
[CmdletBinding(DefaultParameterSetName = 'Global')]
Param(
[Parameter(ParameterSetName="Global")]
[ArgumentCompletions('Title', 'Url', 'SingleLine', 'MultiLine')]
[String]$ActiveTab,
[Parameter(ParameterSetName="Global")]
[Switch]$ActiveVideo,
[Parameter(ParameterSetName="Global")]
[ArgumentCompletions('Title', 'Url')]
[String]$AllTabs,
[Parameter(ParameterSetName="History")]
[String]$History,
#These should only be available when parameter "-History" is present
[Parameter(ParameterSetName="History")]
[Switch]$Title,
[Parameter(ParameterSetName="History")]
[Switch]$URL,
[Parameter(ParameterSetName="History")]
[Switch]$SingleLine,
[Parameter(ParameterSetName="History")]
[Switch]$MultiLine)
Begin{
}
process {
Switch ($PSBoundParameters.Keys){
'ActiveTab'{
}
'AllTabs'{
}
'History'{
$PSCmdlet.ParameterSetName
}
}
}
}
I am struggling with integrating parameter sets into it. I dont know if this is the behaviour to be expected or not.
The behaviour I am expecting is: if parameter -History
is not present then parameters
-Title
-URL
-SingleLine
-MultiLine
SHOULD not be avaible for use.
Yet if I type Get-Firefox
and then press <Tab>
the paramters belonging to ParameterSetName="History"
are suggested by Powershell.
I thought maybe this is just a case of Powershell not being smart enough to hide these parameters from autcompletion.
Yet I can also use the history parameter with any other parameters like, Get-Firefox -ActiveTab -SingleLine
.
Is my code wrong or have I missunderstood this and my expected behaviour is not possible?
Any help would be really wellcome
CodePudding user response:
You can use Dynamic Parameters
to define at runtime these parameters that should be only available if -History
is used. In this example I'm using a loop to instantiate all the RuntimeDefinedParameter
because they're all of the same type ([switch]
) and their parameter declaration is just belonging to the ParameterSetName = 'History'
however the recommendation would be to define each one of them manually instead of using a loop.
function Get-Firefox {
[CmdletBinding(DefaultParameterSetName = 'Global')]
Param(
[Parameter(ParameterSetName="Global")]
[ArgumentCompletions('Title', 'Url', 'SingleLine', 'MultiLine')]
[String] $ActiveTab,
[Parameter(ParameterSetName="Global")]
[Switch] $ActiveVideo,
[Parameter(ParameterSetName="Global")]
[ArgumentCompletions('Title', 'Url')]
[String] $AllTabs,
[Parameter(ParameterSetName="History")]
[String] $History
)
DynamicParam {
if($PSCmdlet.ParameterSetName -eq 'History') {
$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
foreach($param in 'Title', 'URL', 'SingleLine', 'MultiLine') {
[Parameter[]] $paramAttribute = [Parameter]@{ ParameterSetName = 'History' }
$runtimeParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param, [switch], $paramAttribute)
$paramDictionary.Add($param, $runtimeParam)
}
return $paramDictionary
}
}
}