Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple powershell switch parameters - can it be optimized?

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.

like image 340
Sergei Avatar asked Feb 03 '14 13:02

Sergei


4 Answers

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'}
    }
}
like image 172
E.V.I.L. Avatar answered Nov 27 '22 08:11

E.V.I.L.


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...

like image 41
Hunter Eidson Avatar answered Nov 27 '22 10:11

Hunter Eidson


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' }
     }
}
like image 26
mjolinor Avatar answered Nov 27 '22 08:11

mjolinor


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.

like image 30
nitzel Avatar answered Nov 27 '22 09:11

nitzel