Home > OS >  Issues with Parameter sets in a function not working as expected
Issues with Parameter sets in a function not working as expected

Time:12-22

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
        }
    }
}
  • Related