Multiple powershell switch parameters - can it be optimized?

24,270

Solution 1

Probably not the most elegant solution, but using parametersets makes powershell do some of the work for you:

#requires -version 2.0

function Get-data {
    [cmdletbinding()]

    param(
        [parameter(parametersetname="network")]
        [switch]$network,
        [parameter(parametersetname="profile")]
        [switch]$profile,
        [parameter(parametersetname="server")]
        [switch]$server,
        [parameter(parametersetname="devicebay")]
        [switch]$devicebay
    )

    $item = $PsCmdlet.ParameterSetName

    $command = "show $item -output=script2"
}

This example will error out if you don't provide one of the switches, but you could probably provide an extra switch that does nothing or errors more gracefully if you want to account for that case...

Solution 2

Another thing you could do instead of all those switch parameters is to use a [ValidateSet]

function Get-Data{
    [cmdletbinding()]

    param(
        [Parameter(Mandatory=$true)]
        [ValidateSet('Network','Profile','Server','DeviceBay')]
        [string]$Item
    )

    Switch ($Item){
        'network' {'Do network stuff'}
        'profile' {'Do profile stuff'}
        'server' {'Do server stuff'}
        'devicebay' {'Do devicebay stuff'}
    }
}

Solution 3

You can add the [cmdletbinding()] keyword so you get $PSBoundParameters, and use that for a switch pipeline:

function Get-data{
    [cmdletbinding()]

    param (
        [switch]$network,
        [switch]$profile,
        [switch]$server,
        [switch]$devicebay
     )
     Switch ($PSBoundParameters.GetEnumerator().
      Where({$_.Value -eq $true}).Key)
     {
       'network'    { 'Do network stuff' }
       'profile'    { 'Do profile stuff'  }
       'server'     { 'Do server stuff' }
       'devicebay'  { 'Do devicebay stuff' }
     }
}

Solution 4

Since you want only one switch to be enabled, an enum might help you. This way, you're not using a switch but a standard parameter - still, the user of the cmdlet can use TAB to autocomplete the values that may be entered.

Just set the type of the parameter to your enum.

Share:
24,270
Sergei
Author by

Sergei

Updated on July 09, 2022

Comments

  • Sergei
    Sergei almost 2 years

    I am trying to write a simple wrapper that accept one parameter for the output. This is how it looks now

    function Get-data{
    param (
        [switch]$network,
        [switch]$profile,
        [switch]$server,
        [switch]$devicebay
     )
    
        if ($network.IsPresent) { $item = "network"}
        elseif ($profile.IsPresent) {$item = "profile"}
        elseif ($server.IsPresent) {$item = "server"}
        elseif ($devicebay.IsPresent){$item = "devicebay"}
    
        $command = "show $item -output=script2"
    }
    

    Clearly this could be optimize but I am struggling to wrap my head around on how I can achieve it .Is there some easy way to ensure only single parameter is accepted and used without resorting to multiple elseif statements?
    Also I would like to provide array of paramters instead doing it the way it is done at the moment.

  • jpaugh
    jpaugh almost 6 years
    And, it could well accept a list of enums (unlike in OP's case), to perform multiple actions. Simple, and elegant!