PowerShell If, ElseIf and Else Statements (With Examples)

In PowerShell, an if statement runs a block of code when its condition is true. Add elseif for more conditions and else for everything else. The condition goes in parentheses and the code in braces:

$diskFreeGB = 42

if ($diskFreeGB -lt 20) {
    'Critical: less than 20 GB free'
}
elseif ($diskFreeGB -lt 50) {
    'Warning: less than 50 GB free'
}
else {
    'Disk space is fine'
}

Output:

Warning: less than 50 GB free

PowerShell checks each condition from the top and runs only the first block that’s true. I ran every example in PowerShell 7.6 and Windows PowerShell 5.1 and note where they differ.

Order your elseif conditions carefully

Since the first true condition wins, a broad check placed first hides the narrower ones below it. A score of 95 gets a D here, until the order is fixed:

$score = 95

if ($score -ge 60)     { 'Grade: D' }
elseif ($score -ge 90) { 'Grade: A' }

if ($score -ge 90)     { 'Grade: A' }
elseif ($score -ge 60) { 'Grade: D' }

Output:

Grade: D
Grade: A
PowerShell elseif order where the first true condition wins
The same 95 gets a D or an A depending on the order (PowerShell 7)

Put the most specific or highest thresholds first. For a long list of exact values, a switch statement reads better, as shown at the end.

Multiple conditions with -and and -or

Join conditions with -and when all must be true, and -or when any one is enough. For a list of allowed values, -in is shorter than a chain of -or:

$age   = 34
$state = 'TX'

if ($age -ge 21 -and $state -eq 'TX') { 'Eligible for the Texas offer' }
if ($state -eq 'CA' -or $state -eq 'TX' -or $state -eq 'NY') { 'Large-state pricing applies' }
if ($state -in 'CA', 'TX', 'NY') { 'Same check with -in' }

Output:

Eligible for the Texas offer
Large-state pricing applies
Same check with -in

When you mix -and and -or, add parentheses. PowerShell gives them equal precedence, which surprises people coming from C#. PowerShell logical operators shows exactly how that goes wrong.

Check if a number is between two values

Combine -ge and -le for an inclusive range. That works for any number, including decimals:

foreach ($temp in 65, 72, 80.5) {
    if ($temp -ge 68 -and $temp -le 78) { "$temp F is in the comfort range" }
    else { "$temp F is outside the comfort range" }
}

"Is 72.5 in 68..78? $(72.5 -in 68..78)"

Output:

65 F is outside the comfort range
72 F is in the comfort range
80.5 F is outside the comfort range
Is 72.5 in 68..78? False
PowerShell if statement to check if a number is between two values
-ge and -le handle decimals, the 68..78 range doesn’t (PowerShell 7)

The range operator 68..78 only holds whole numbers, so -in misses 72.5. Use it for things like years or item counts, not measurements.

If greater than 0, and why CSV values trip it up

For numbers, -gt 0 works as expected, and $null counts as not greater than 0:

foreach ($value in 5, 0, -3, $null) {
    $label = if ($null -eq $value) { 'null' } else { $value }
    if ($value -gt 0) { "$label is greater than 0" } else { "$label is not greater than 0" }
}

Output:

5 is greater than 0
0 is not greater than 0
-3 is not greater than 0
null is not greater than 0

CSV and text values

Import-Csv and ConvertFrom-Csv return text, and text compares character by character. Here’s the same check on text and on numbers:

$accounts = @'
Name,Balance
Alice,250
Bob,99
Dan,-40
'@ | ConvertFrom-Csv

foreach ($a in $accounts) {
    '{0,-6} as text -gt 100: {1,-6} as number: {2}' -f $a.Name, ($a.Balance -gt 100), ([decimal]$a.Balance -gt 100)
}

Output in PowerShell 7:

Alice  as text -gt 100: True   as number: True
Bob    as text -gt 100: True   as number: False
Dan    as text -gt 100: False  as number: False

Output in Windows PowerShell 5.1:

Alice  as text -gt 100: True   as number: True
Bob    as text -gt 100: True   as number: False
Dan    as text -gt 100: True   as number: False
PowerShell if greater than on CSV text values gives wrong results
As text, 99 and -40 both count as greater than 100 in Windows PowerShell 5.1

As text, 99 beats 100 in both versions, and -40 even gives different answers in 7 and 5.1. Cast first with [int] or [decimal]. Comparison operators explains the rule that the left side decides the type.

Assign the result of an if statement

An if statement can produce a value, so you can assign it straight to a variable. This works in both versions:

$hour = 14

$greeting = if ($hour -lt 12) { 'Good morning' } elseif ($hour -lt 17) { 'Good afternoon' } else { 'Good evening' }
$greeting

Output:

Good afternoon

The ternary operator in PowerShell 7

PowerShell 7 adds the shorter condition ? a : b form. Windows PowerShell 5.1 treats it as a syntax error, so use the if form above in scripts that must run there:

$stock = 0
$status = $stock -gt 0 ? 'In stock' : 'Sold out'
$status

Output in PowerShell 7:

Sold out

Use switch instead of a long elseif chain

When you compare one value against many exact options, switch is easier to read and extend:

$state = 'WA'

switch ($state) {
    'TX'    { 'Central Time' }
    'CA'    { 'Pacific Time' }
    'WA'    { 'Pacific Time' }
    'NY'    { 'Eastern Time' }
    default { 'Check the time zone list' }
}

Output:

Pacific Time

switch also handles wildcards and regex. See the PowerShell switch statement and Microsoft’s about_Switch. The if statement itself is documented in