Multiple Switch Parameters in Advanced Function

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Dave Wyatt Dave Wyatt 2 years, 2 months ago.

  • Author
    Posts
  • #19115
    Profile photo of I Am Sir Ask Alot
    I Am Sir Ask Alot
    Participant

    Okay, so here is an advanced function I threw together as a template with switch parameters. What I would LOVE to know is if there is a better, more efficient way to get the combinations of parameters processed without all of the ElseIf statements. If not, no worries, if so, PLEASE make me privy to this.

    {Function Do-Something
    {
        [cmdletbinding()] 
         
            Param  
            (              
                 [Parameter()]    
                 [Alias('P1')]
                 [switch]$Param1,
             
                 [Parameter()]   
                 [Alias('P2')]
                 [switch]$Param2,
    
                 [Parameter()]   
                 [Alias('P3')]
                 [switch]$Param3,
             
                 [Parameter()]   
                 [Alias('P4')]
                 [switch]$Param4,
    
                 [Parameter()] 
                 [Alias('P5')]
                 [switch]$Param5
            )
    
            Begin {}
    
            Process 
            {
                #Begin Processing Param1 combinations
    
                If ($Param1 -and $Param2 -and $Param3 -and $Param4 -and $Param5)
                {
                    Write-Output "All 5 parameters are being used"
    
                    Write-Output "Param1, Param2, Param3, Param4, and Param5"
                }
                
                ElseIf ($Param1 -and $Param2 -and $Param3 -and $Param4)
                {
                    Write-Output "4 parameters are being used"
    
                    Write-Output "Param1, Param2, Param3, and Param4"
                }
    
                ElseIf ($Param1 -and $Param2 -and $Param3)
                {
                    Write-Output "3 parameters are being used"
    
                    Write-Output "Param1, Param2, and Param3"
                }
    
                ElseIf ($Param1 -and $Param2)
                {
                    Write-Output "2 parameters are being used"
    
                    Write-Output "Param1, and Param2"
                }
    
                ElseIf ($Param1)
                {
                    Write-Output "1 parameter is being used"
    
                    Write-Output "Param1"
                }
    
                #Begin Processing Param2 combinations
    
                ElseIf ($Param2 -and $Param3 -and $Param4 -and $Param5)
                {
                    Write-Output "4 parameters are being used"
    
                    Write-Output "Param2, Param3, Param4, and Param5"
                }
    
                ElseIf ($Param2 -and $Param3 -and $Param4)
                {
                    Write-Output "3 parameters are being used"
    
                    Write-Output "Param2, Param3, and Param4"
                }
    
                ElseIf ($Param2 -and $Param3)
                {
                    Write-Output "2 parameters are being used"
    
                    Write-Output "Param2 and Param3"
                }
    
                ElseIf ($Param2)
                {
                    Write-Output "1 parameter is being used"
    
                    Write-Output "Param2"
                }
    
                #Begin Processing Param3 combinations
    
                ElseIf($Param3 -and $Param4 -and $Param5)
                {
                    Write-Output "3 parameters are being used"
    
                    Write-Output "Param3, Param4, and Param5"
                }
    
                ElseIf ($Param3 -and $Param4)
                {
                    Write-Output "2 parameters are being used"
    
                    Write-Output "Param3 and Param4"
                }
    
                ElseIf ($Param3)
                {
                    Write-Output "1 parameter are being used"
    
                    Write-Output "Param3"
                }
    
                #Begin Processing Param4 combinations
    
                ElseIf($Param4 -and $Param5)
                {
                    Write-Output "2 parameters are being used"
    
                    Write-Output "Param4 and Param5"
                }
    
                ElseIf ($Param4)
                {
                    Write-Output "1 parameters is being used"
    
                    Write-Output "Param4"
                }
    
                #Begin Processing Param5 combinations
    
                ElseIf($Param5)
                {
                    Write-Output "1 parameter is being used"
    
                    Write-Output "Param5"
                }
            }
    
            End {}
    } 
    
    Do-Something -P1 -P2 -P3 -P4 -P5}

    As always, thanks for your help

  • #19119
    Profile photo of Tim Pringle
    Tim Pringle
    Participant

    Hey fella,

    Try something like this

    Function Do-Something
    {
        [cmdletbinding()]
        
        Param
        (
            [Parameter()]
            [Alias('P1')]
            [switch]$Param1,
            
            [Parameter()]
            [Alias('P2')]
            [switch]$Param2,
            
            [Parameter()]
            [Alias('P3')]
            [switch]$Param3,
            
            [Parameter()]
            [Alias('P4')]
            [switch]$Param4,
            
            [Parameter()]
            [Alias('P5')]
            [switch]$Param5
        )
        
        
        
        Process
        {
    
            $Parameters = (Get-Command -Name $MyInvocation.InvocationName).Parameters | Select -ExpandProperty Keys | Where-Object { $_ -NotIn ('Verbose', 'ErrorAction', 'WarningAction', 'PipelineVariable', 'OutBuffer', 'Debug', 'ErrorAction','WarningAction', 'ErrorVariable', 'WarningVariable', 'OutVariable') }
            $TotalParameters = $parameters.count
            
            $ParametersPassed = $PSBoundParameters.Count
       
            If ($ParametersPassed -eq $TotalParameters) { Write-Output "All $totalParameters parameters are being used" }
            ElseIf ($ParametersPassed -eq 1) { Write-Output "1 parameter is being used" }
            Else { Write-Output "$parametersPassed parameters are being used" }
            
            [string] $psBoundParameters.Keys
            
            
        }
    }
    
    PS C:\Windows\system32> Do-Something -Param1 -Param2 -Param3 -Param4
    4 parameters are being used
    Param1 Param2 Param3 Param4
    
    PS C:\Windows\system32> Do-Something -Param1
    1 parameter is being used
    Param1
    
    PS C:\Windows\system32> Do-Something -Param1 -Param2
    2 parameters are being used
    Param1 Param2
    
    PS C:\Windows\system32> Do-Something -Param1 -Param2 -Param3 -Param4 -Param5
    All 5 parameters are being used
    Param1 Param2 Param3 Param4 Param5
    
  • #19122
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    One thing that can be a but funny about using the PSBoundParameters collection is that it's possible to pass $false to a switch parameter. Looking at PSBoundParameters tests for presence, but not value. The same type of approach works, though; count up the $true values in a single pass, instead of having If statements for every possible combination:

    Function Do-Something
    {
        [cmdletbinding()]
     
        Param
        (
            [Parameter()]
            [Alias('P1')]
            [switch]$Param1,
     
            [Parameter()]
            [Alias('P2')]
            [switch]$Param2,
     
            [Parameter()]
            [Alias('P3')]
            [switch]$Param3,
     
            [Parameter()]
            [Alias('P4')]
            [switch]$Param4,
     
            [Parameter()]
            [Alias('P5')]
            [switch]$Param5
        )
        
        $trueSwitches = @(     
            foreach ($paramName in 'Param1', 'Param2', 'Param3', 'Param4', 'Param5')
            {
                if ($PSBoundParameters[$paramName]) { $paramName }
            }
        )
    
        $plural = 's are'
        if ($trueSwitches.Count -eq 1) { $plural = ' is' }
    
        $all = $null
        if ($trueSwitches.Count -eq 5) { $all = 'All ' }
    
        $paramString = $trueSwitches -join ', ' -replace ', ([^,]+)$', ' and $1'
    
        Write-Output ('{0}{1} parameter{2} being used' -f $all, $trueSwitches.Count, $plural)
        Write-Output $paramString
     }
    
    
  • #19184
    Profile photo of I Am Sir Ask Alot
    I Am Sir Ask Alot
    Participant

    Thanks a bunch. I will see how I can incorporate this into my actual code. What are the {0} {1} referred to as and where I can read up on how to use them? Thanks again

  • #19185
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    The -f (format) operator is covered in the about_Operators help file, though most of the information you'll find in the MSDN articles that it links you to.

You must be logged in to reply to this topic.