powershell

What is the right way to check a switch parameter


What is the right way to check value of a switch?

function testSwitch
{
    Param(
        [switch] $swth
    )

    Write-Host "Value of swth is $swth"

    if($swth.IsPresent){
        Write-host "Switch is present"
    }

    if($swth){
        Write-Host "Switch is truthy"
    }

}

testSwitch -swth

I know both if statement works fine, but how?


Solution

  • $swth.IsPresent and $swth can be used interchangeably, because in a Boolean context (such as an if conditional) $swth (an instance of type [switch] representing a switch parameter) effectively returns the value of the .IsPresent property.[1]

    In fact, $swth is probably preferable[2], not just for concision, but because the .IsPresent property is somewhat confusingly named:

    .IsPresent doesn't indicate the presence of the switch per se, but whether its value is $true.

    While specifying a switch by itself - -swth - implies both, the same isn't true if you explicitly set it to $false: Passing -swth:$false makes .IsPresent return $false, even though the switch is clearly present.

    Passing $false explicitly isn't common, but has its uses, such as when opting out of a confirmation prompt with -Confirm:$false, and when programmatically constructing arguments.

    Therefore, if you want to distinguish between the user not passing the switch and the user passing it with value $false, .IsPresent won't help you - you'll have to use $PSBoundParameters.ContainsKey('swth')


    [1] On conversion to Boolean, which happens in method LanguagePrimitives.IsTrue(), PowerShell calls a [switch] instance's .ToBool() method, which in turn returns the private backing variable behind the .IsPresent property.

    [2] The only caveat is that you must be aware that $swth is not a Boolean ([bool]), but of type [switch], which may matter in other contexts.