While working on some updates to the PSAtera module, I came across an interesting situation that didn't seem to have a straightforward answer. The new updates to the Get-AteraTickets command add a number of switch options for narrowing tickets down to only tickets with certain status', so I added some new switch options:

function Get-AteraTickets {
    param(
    	[switch] $Open,
        [switch] $Pending,
        [switch] $Resolved,
        [switch] $Closed,
        ...
    )
}

To make the command more intuitive, I wanted to change the logic so that if no switches were set, the command would only return Open and Pending tickets. The first pass added an if statement immediately after the parameters:

function Get-AteraTickets {
    param(
    	[switch] $Open,
        [switch] $Pending,
        [switch] $Resolved,
        [switch] $Closed,
        ...
    )
    if (!($Open -or $Pending -or $Resolved -or $Closed)) {
    	$Open = $true
        $Pending = $true
    }
}

This is an okay solution to me, but it breaks when someone calls something like: Get-AteraTickets -Open:$false -Pending:$false -Resolved:$true -Closed:$true. This may seem pretty rare, but it becomes increasingly likely if someone is dynamically creating the argument set and passing it in to the command.

So after playing with the code, I came up with a new solution:

function Get-AteraTickets {
    param(
    	[switch] $Open=!($PSBoundParameters.Keys | Where-Object {
            @("Pending","Resolved", "Closed") -match $_
        }),
        [switch] $Pending=!($PSBoundParameters.Keys | Where-Object {
            @("Open","Resolved", "Closed") -match $_
        }),
        [switch] $Resolved,
        [switch] $Closed,
        ...
    )
}

This solution is pretty terse and maybe not the easiest to read, but the value of Open and Pending are defaulted to the inverse of the presence of any of the other switches.

If you know a better way to set default parameters when nothing is passed in, send me a message.