Improve code to use optional switch parameter in PowerShell

3.3k views Asked by At

I have a Powershell function that wraps Invoke-WebRequest. Depending on the value of parameter $verbose I want to use -Verbose or not.

The code I have wrote using an API does the work... but I feel there should be a better way with less lines of code. It feels wrong to have twice the line with the Invoke-WebRequest

So my question is: Is there a best way in Powershell to deal with switch parameters?

Here is the function:

function Invoke-MarkLogicManagementAPI($server, $apiFolder, $adminCredentials, $HTTPmethod, $body, $verbose)
{
    $resp1HTTPCode= "Not set"
    try
    {
        $uri = "http://$($server):8002/manage/v2/$apiFolder"
        if ($verbose -eq $true)
        {
            $resp1 = Invoke-WebRequest -Uri $uri -Body $body -Method "$HTTPmethod" -Credential $adminCredentials -ContentType "application/json" -ErrorAction SilentlyContinue -Verbose
        }
        else
        {
            $resp1 = Invoke-WebRequest -Uri $uri -Body $body -Method "$HTTPmethod" -Credential $adminCredentials -ContentType "application/json" -ErrorAction SilentlyContinue
        }
        $resp1HTTPCode = $resp1.StatusCode
    }
    catch [Exception]
    {
        $resp1HTTPCode = $_.Exception.Response.StatusCode.Value__
    }

    return $resp1HTTPCode
}
2

There are 2 answers

3
Martin Brandl On BEST ANSWER

Yes, you can pass a boolean to a switch parameter. In your case:

-Verbose:$verbose

example:

function DoSomething
{
    [CmdletBinding()]
    Param()
    Write-Verbose "output"
}

DoSomething -verbose:$true # Does write output
DoSomething -verbose:$false # no output
0
Matt On

Since your question involves Verbose using [CmdletBinding()] is an easy way to account for that variance. I wanted to introduce to you splatting as well which is a great way to pass a varying number of parameters to a cmdlet while not having to actually write out each command.

function Get-Bagels{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$True)]
        [string]$Filter,
        [switch]$Recurse=$false,
        [switch]$FilesOnly 
    )

    $parameters = @{
        Filter = $filter
        Recurse = $recurse
    }

    If($filesonly){$parameters.File=$True}

    Get-ChildItem @parameters
}

A really simple example is done be creating a hashtable $parameters and adding the parameters we want to pass to Get-ChildItem.I show a couple ways of populating the table notably you can see that the file switch is conditionally added with a small if.

This way no matter what parameters are being used the cmdlet call is the same every time.

So the following function calls will work

Get-Bagels -Filter "*.txt"
Get-Bagels -Filter "*.txt" -Recurse
Get-Bagels -Filter "*.txt" -FilesOnly
Get-Bagels -Filter "*.txt" -Recurse:$False -FilesOnly