Logical operators combine boolean expressions and control how conditions are evaluated. PowerShell uses word-based, hyphen-prefixed operators (-and, -or, -not, -xor) rather than symbolic equivalents like &&, ||, or !. These operators are essential for building complex conditions in if, elseif, while, do, and switch statements.
Operators at a Glance
| Operator | Type | Description | Example |
|---|---|---|---|
-and |
Binary | Returns $true only if both operands are true |
$a -and $b |
-or |
Binary | Returns $true if at least one operand is true |
$a -or $b |
-not |
Unary | Negates a boolean value | -not $a |
-xor |
Binary | Returns $true if exactly one operand is true |
$a -xor $b |
Truth Tables
-and (Logical AND)
| Left | Right | Result |
|---|---|---|
$true |
$true |
$true |
$true |
$false |
$false |
$false |
$true |
$false |
$false |
$false |
$false |
-or (Logical OR)
| Left | Right | Result |
|---|---|---|
$true |
$true |
$true |
$true |
$false |
$true |
$false |
$true |
$true |
$false |
$false |
$false |
-not (Logical NOT)
| Operand | Result |
|---|---|
$true |
$false |
$false |
$true |
-xor (Logical XOR)
| Left | Right | Result |
|---|---|---|
$true |
$true |
$false |
$true |
$false |
$true |
$false |
$true |
$true |
$false |
$false |
$false |
Basic Usage
$isAdmin = $true
$isOwner = $false
[PSCustomObject]@{
AndResult = ($isAdmin -and $isOwner) # False
OrResult = ($isAdmin -or $isOwner) # True
NotResult = (-not $isAdmin) # False
XorResult = ($isAdmin -xor $isOwner) # True
}pwsh ./logical-basics.ps1AndResult OrResult NotResult XorResult
--------- -------- --------- ---------
False True False TrueShort-Circuit Evaluation
PowerShell's -and and -or operators use short-circuit evaluation, meaning the right-hand operand is evaluated only when necessary.
| Operator | Short-Circuit Behavior |
|---|---|
-and |
If the left operand is $false, the right operand is not evaluated; the result is $false. |
-or |
If the left operand is $true, the right operand is not evaluated; the result is $true. |
-xor |
No short-circuit: both operands must be evaluated to determine if exactly one is true. |
-not |
Unary; simply evaluates its single operand. |
Demonstrating Short-Circuit Behavior
function Test-SideEffect {
Write-Host " [right side evaluated]"
return $true
}
Write-Host "A: `$false -and ..."
$result = $false -and (Test-SideEffect)
Write-Host "Result: $result"
Write-Host "B: `$true -or ..."
$result = $true -or (Test-SideEffect)
Write-Host "Result: $result"
Write-Host "C: `$true -and ..."
$result = $true -and (Test-SideEffect)
Write-Host "Result: $result"A: $false -and ...
Result: False
B: $true -or ...
Result: True
C: $true -and ...
[right side evaluated]
Result: Truewhere:
- In case A,
-andshort-circuits because the left side is$false;Test-SideEffectis never called. - In case B,
-orshort-circuits because the left side is$true;Test-SideEffectis never called. - In case C,
-andmust evaluate the right side because the left side is$true.
Why Short-Circuiting Matters
Short-circuit evaluation does more than just optimize performance; it also prevents runtime errors and avoids unintended side effects.
if ($user -and $user.IsAdmin) {
"User is an administrator."
} else {
"User is not an administrator or is not logged in."
}Without short-circuiting, $user.IsAdmin would throw an error when $user is $null.
Operator Precedence
When multiple logical operators appear in the same expression, PowerShell evaluates them according to the following precedence rules:
-nothas higher precedence than the binary logical operators.-and,-or, and-xorhave equal precedence and are evaluated from left to right.- Parentheses override the normal evaluation order.
$result1 = $true -or $false -and $false
$result2 = $true -or ($false -and $false)
[PSCustomObject]@{
WithoutParentheses = $result1 # False
WithParentheses = $result2 # False
}WithoutParentheses WithParentheses
------------------ ---------------
False TrueBecause -or and -and have equal precedence, the first expression is evaluated from left to right:
($true -or $false) -and $falseTruthiness in PowerShell
Logical operators can accept non-boolean values. PowerShell converts them to booleans using these rules:
| Value | Boolean Equivalent |
|---|---|
$null |
$false |
0 |
$false |
0.0 |
$false |
"" (empty string) |
$false |
@() (empty array) |
$false |
1 |
$true |
-1 |
$true |
"false" (non-empty string) |
$true |
@(0) (non-empty array) |
$true |
[bool]$null
[bool]0
[bool]""
[bool]@()
[bool]"false"
[bool]@(0)
[bool]@(1)False
False
False
False
True
False
TruePractical Examples
1. Validating Configuration Settings
$port = 443
$protocol = "HTTPS"
$useSSL = $true
$isValidPort = ($port -gt 0 -and $port -le 65535)
$isValidProtocol = ($protocol -eq "HTTP" -or $protocol -eq "HTTPS")
$isSecure = ($useSSL -and $protocol -eq "HTTPS")
if ($isValidPort -and $isValidProtocol -and $isSecure) {
"Configuration is valid and secure."
} else {
"Configuration is invalid or insecure."
}Configuration is valid and secure.2. Mutually Exclusive Options with -xor
$useSSL = $true
$useTLS = $true
if ($useSSL -xor $useTLS) {
"Exactly one security protocol is selected."
} else {
"Select exactly one security protocol."
}Select exactly one security protocol.3. Combining Multiple Conditions
$isAdmin = $false
$isOwner = $true
$isAuditor = $false
$canManage = $isAdmin -or $isOwner
$canRead = $canManage -or $isAuditor
$isExclusive = $isAdmin -xor $isOwner
[PSCustomObject]@{
CanManage = $canManage # True
CanRead = $canRead # True
IsExclusive = $isExclusive # True
}CanManage CanRead IsExclusive
--------- ------- -----------
True True TrueBest Practices
- Use parentheses to group conditions and make intent clear.
- Prefer
-notover!in scripts for readability and consistency. - Leverage short-circuiting for safe null checks and guard clauses.
- Avoid overly complex one-liners; assign intermediate booleans to named variables.
- Remember that
-xordoes not short-circuit: both operands are always evaluated. - Do not rely on truthiness for string comparisons; use
-eq,-like, or-matchinstead.