How to Convert a String to a Boolean in PowerShell (and Boolean to Int)

To convert a string to a Boolean in PowerShell, use [System.Convert]::ToBoolean(). It turns the text True or False into the matching Boolean value, ignoring case:

$setting = 'False'

$flag = [System.Convert]::ToBoolean($setting)
"'$setting' converted with ToBoolean: $flag ($($flag.GetType().Name))"

Output:

'False' converted with ToBoolean: False (Boolean)

Don’t cast with [bool] for this. [bool]'False' returns True, which I show next. I ran every example in PowerShell 7.6 and Windows PowerShell 5.1, with the same results.

Why [bool]’False’ is True

A [bool] cast doesn’t read the text. It only checks whether the string is empty. Any string with at least one character, even ‘False’, ‘0’ or a space, becomes True:

foreach ($text in 'True', 'False', 'false', '0', '', ' ') {
    '[bool]{0,-8} -> {1}' -f "'$text'", [bool]$text
}

Output:

[bool]'True'   -> True
[bool]'False'  -> True
[bool]'false'  -> True
[bool]'0'      -> True
[bool]''       -> False
[bool]' '      -> True
PowerShell bool cast of the string False returns True
Every non-empty string casts to True, including ‘False’ and ‘0’ (PowerShell 7)

The cast is only useful for asking “is this string empty?”

Convert with ToBoolean

ToBoolean accepts True and False in any case, with spaces around them. Anything else, including yes and 1, throws an error:

foreach ($text in 'True', 'false', ' FALSE ', 'yes', '1') {
    try { '{0,-9} -> {1}' -f "'$text'", [System.Convert]::ToBoolean($text) }
    catch { '{0,-9} -> Failed. Not a True or False string' -f "'$text'" }
}

Output:

'True'    -> True
'false'   -> False
' FALSE ' -> False
'yes'     -> Failed. Not a True or False string
'1'       -> Failed. Not a True or False string
PowerShell Convert ToBoolean converts True and False strings
True and False convert, while yes and 1 fail (Windows PowerShell 5.1)

That strictness is useful. A typo like Flase fails loudly instead of quietly becoming the wrong value. The Convert.ToBoolean documentation covers the other types it accepts.

Check first with TryParse

[bool]::TryParse returns True or False instead of throwing, and puts the result in a [ref] variable. Use it when bad input is expected:

$inputs = 'true', 'Yes', 'FALSE'

foreach ($text in $inputs) {
    $result = $false
    if ([bool]::TryParse($text, [ref]$result)) { "'$text' parsed as $result" }
    else { "'$text' isn't True or False, so it was rejected" }
}

Output:

'true' parsed as True
'Yes' isn't True or False, so it was rejected
'FALSE' parsed as False

Convert yes/no, 1/0 and on/off

Config files and forms often use yes/no or 1/0. A small function with a switch statement handles all of them and still rejects anything unexpected:

function ConvertTo-Boolean {
    param([Parameter(Mandatory)] [AllowEmptyString()] [string]$Text)
    switch ($Text.Trim()) {
        { $_ -in 'true', 'yes', 'y', '1', 'on', 'enabled' }    { return $true }
        { $_ -in 'false', 'no', 'n', '0', 'off', 'disabled', '' } { return $false }
        default { throw "Can't convert '$Text' to a Boolean" }
    }
}

foreach ($text in 'Yes', 'n', '1', 'OFF', 'Enabled') {
    '{0,-9} -> {1}' -f "'$text'", (ConvertTo-Boolean -Text $text)
}
try { ConvertTo-Boolean -Text 'maybe' } catch { "Failed. $($_.Exception.Message)" }

Output:

'Yes'     -> True
'n'       -> False
'1'       -> True
'OFF'     -> False
'Enabled' -> True
Failed. Can't convert 'maybe' to a Boolean
PowerShell convert yes no on off string to Boolean
Yes, n, 1, OFF and Enabled all convert, and maybe is rejected (PowerShell 7)

-in compares without case, so Yes, YES and yes all match. Add any other words your data uses to the two lists.

Environment variables are always strings

This is where the empty-string rule causes real bugs. An environment variable set to false is still a non-empty string, so a plain if treats it as on:

$env:FEATURE_REPORTS = 'false'

if ($env:FEATURE_REPORTS) { 'Plain if: reports are ON (wrong)' }
if ([System.Convert]::ToBoolean($env:FEATURE_REPORTS)) { 'Converted: reports are ON' }
else { 'Converted: reports are OFF' }

Output:

Plain if: reports are ON (wrong)
Converted: reports are OFF

Convert the value before testing it. Setting and reading environment variables covers the rest.

Comparing strings to $true

-eq converts the right side to the type of the left side. With $true on the left, the string becomes a Boolean, so any non-empty text matches:

"`$true -eq 'false'  -> $($true -eq 'false')"
"'false' -eq `$true  -> $('false' -eq $true)"
"'True' -eq `$true   -> $('True' -eq $true)"

Output:

$true -eq 'false'  -> True
'false' -eq $true  -> False
'True' -eq $true   -> True

Put $true on the left only after you’ve converted the string. Comparison operators explains the left-side rule.

Convert a Boolean to an integer

Cast it with [int]: True becomes 1 and False becomes 0. PowerShell also does this in math, which makes counting passed checks easy:

"[int]`$true  = $([int]$true)"
"[int]`$false = $([int]$false)"
"`$true + `$true = $($true + $true)"

$checks = $true, $false, $true, $true
"Passed checks: $(($checks | Where-Object { $_ }).Count) of $($checks.Count)"

Output:

[int]$true  = 1
[int]$false = 0
$true + $true = 2
Passed checks: 3 of 4

<