Skip to content

If Statements & Conditional Logic

Note

Learn how to make decisions in your scripts using if/else statements and comparison operators.

Overview

Conditional statements let your scripts make decisions based on whether something is true or false. Think of it like: "If this condition is true, do this; otherwise, do that." This is fundamental to creating scripts that respond to different situations.

Basic Syntax

# Simple if statement
if (condition) {
    # Code runs if condition is true
}

# If-else
if (condition) {
    # Runs if true
} else {
    # Runs if false
}

# If-elseif-else (multiple conditions)
if (condition1) {
    # Runs if condition1 is true
} elseif (condition2) {
    # Runs if condition2 is true
} else {
    # Runs if all conditions are false
}

Key Points

  • Condition must evaluate to $true or $false
  • Use curly braces {} for code blocks
  • elseif is one word (not "else if")
  • PowerShell comparison operators are different: -eq, -ne, -gt, etc. (not ==, !=, >)

Comparison Operators

Equality Operators

-eq     # Equal to
-ne     # Not equal to
-gt     # Greater than
-ge     # Greater than or equal to
-lt     # Less than
-le     # Less than or equal to

# Examples
5 -eq 5         # $true
"test" -eq "TEST"   # $true (case-insensitive by default)
10 -gt 5        # $true
3 -le 3         # $true

Case-Sensitive Operators

-ceq    # Case-sensitive equal
-cne    # Case-sensitive not equal

# Examples
"test" -eq "TEST"   # $true (case-insensitive)
"test" -ceq "TEST"  # $false (case-sensitive)

Logical Operators

-and    # Both conditions must be true
-or     # At least one condition must be true
-not    # Reverses the condition
!       # Also means NOT (same as -not)

# Examples
(5 -gt 3) -and (10 -lt 20)  # $true (both are true)
(5 -gt 10) -or (3 -lt 5)    # $true (second is true)
-not ($false)               # $true
!(5 -eq 10)                 # $true

Pattern Matching

-like       # Wildcard matching
-notlike    # Doesn't match wildcard
-match      # Regex matching
-notmatch   # Doesn't match regex

# Examples
"PowerShell" -like "Power*"     # $true
"test.txt" -like "*.txt"        # $true
"abc123" -match "\d+"           # $true (contains numbers)

Containment Operators

-contains       # Array contains value
-notcontains    # Array doesn't contain value
-in             # Value is in array
-notin          # Value is not in array

# Examples
$colors = "Red", "Green", "Blue"
$colors -contains "Red"     # $true
"Yellow" -in $colors        # $false

Common Use Cases

Use Case 1: Check if File Exists

What it does: Perform action only if a file exists

$filePath = "C:\Temp\report.txt"

if (Test-Path -Path $filePath) {
    Write-Output "File exists, reading content..."
    Get-Content -Path $filePath
} else {
    Write-Output "File not found!"
}

Use Case 2: Multiple Conditions

What it does: Check several conditions and respond appropriately

$diskSpace = (Get-PSDrive C).Free / 1GB

if ($diskSpace -lt 10) {
    Write-Output "CRITICAL: Less than 10GB free!"
} elseif ($diskSpace -lt 50) {
    Write-Output "WARNING: Less than 50GB free"
} else {
    Write-Output "Disk space is healthy: $diskSpace GB free"
}

Output:

WARNING: Less than 50GB free

Use Case 3: Complex Conditions

What it does: Combine multiple checks with AND/OR logic

$service = Get-Service -Name "Spooler"

if (($service.Status -eq "Running") -and ($service.StartType -eq "Automatic")) {
    Write-Output "Service is running and set to automatic - all good!"
} elseif ($service.Status -eq "Stopped") {
    Write-Output "Service is stopped, attempting to start..."
    Start-Service -Name $service.Name
} else {
    Write-Output "Service state: $($service.Status)"
}

Real-World Examples

Example: Validate User Input

Scenario: Check if user entered valid data before processing

$age = Read-Host "Enter your age"

# Check if input is a valid number
if ($age -match "^\d+$") {
    $ageNumber = [int]$age

    if ($ageNumber -lt 18) {
        Write-Output "You must be 18 or older"
    } elseif ($ageNumber -gt 120) {
        Write-Output "Invalid age entered"
    } else {
        Write-Output "Age verified: $ageNumber"
    }
} else {
    Write-Output "Please enter a valid number"
}

Explanation: First we check if the input is numeric, then we validate the range. This prevents errors from trying to convert invalid input.

Example: Process Files Based on Extension

Scenario: Handle different file types differently

$file = Get-Item "C:\Temp\document.pdf"

if ($file.Extension -eq ".txt") {
    Write-Output "Text file - displaying content..."
    Get-Content -Path $file.FullName
} elseif ($file.Extension -in @(".jpg", ".png", ".gif")) {
    Write-Output "Image file - opening in default viewer..."
    Invoke-Item -Path $file.FullName
} elseif ($file.Extension -eq ".pdf") {
    Write-Output "PDF file - size: $([math]::Round($file.Length/1MB, 2)) MB"
} else {
    Write-Output "Unknown file type: $($file.Extension)"
}

Output:

PDF file - size: 2.34 MB

Example: Environment-Based Configuration

Scenario: Use different settings based on environment

$environment = "Production"  # Could be: Development, Testing, Production
$serverName = $env:COMPUTERNAME

if ($environment -eq "Production") {
    $connectionString = "Server=prod-sql01;Database=MainDB"
    $logLevel = "Error"
    $debugMode = $false
} elseif ($environment -eq "Testing") {
    $connectionString = "Server=test-sql01;Database=TestDB"
    $logLevel = "Warning"
    $debugMode = $true
} else {
    $connectionString = "Server=localhost;Database=DevDB"
    $logLevel = "Verbose"
    $debugMode = $true
}

Write-Output "Environment: $environment"
Write-Output "Connecting to: $connectionString"
Write-Output "Debug mode: $debugMode"

Switch Statements (Alternative to Multiple If/ElseIf)

For checking one variable against many possible values, switch is cleaner than multiple elseif statements:

$dayOfWeek = (Get-Date).DayOfWeek

switch ($dayOfWeek) {
    "Monday"    { Write-Output "Start of work week" }
    "Friday"    { Write-Output "Almost weekend!" }
    "Saturday"  { Write-Output "Weekend - relax!" }
    "Sunday"    { Write-Output "Weekend - relax!" }
    default     { Write-Output "Regular work day" }
}

# Switch with conditions
$number = 42

switch ($number) {
    {$_ -lt 0}    { Write-Output "Negative" }
    {$_ -eq 0}    { Write-Output "Zero" }
    {$_ -le 10}   { Write-Output "Between 1 and 10" }
    {$_ -le 100}  { Write-Output "Between 11 and 100" }
    default       { Write-Output "Greater than 100" }
}

Truthy and Falsy Values

# These evaluate to $false
if ($false) { }         # Boolean false
if ($null) { }          # Null
if (0) { }              # Zero
if ("") { }             # Empty string
if (@()) { }            # Empty array

# These evaluate to $true
if ($true) { }          # Boolean true
if (1) { }              # Non-zero number
if ("text") { }         # Non-empty string
if (@(1,2,3)) { }       # Non-empty array
if ((Get-Process)) { }  # Object exists

Null Checking

# Check if variable is null
if ($null -eq $myVariable) {
    Write-Output "Variable is null"
}

# Check if variable is NOT null
if ($null -ne $myVariable) {
    Write-Output "Variable has a value"
}

# Safe property access (PowerShell 7+)
$process = Get-Process -Name "nonexistent" -ErrorAction SilentlyContinue
if ($process?.Name) {
    Write-Output "Process name: $($process.Name)"
}

Tips & Tricks

Use Test-Path for File/Folder Checks

# Check if path exists (file or folder)
if (Test-Path -Path "C:\Temp") {
    Write-Output "Path exists"
}

# Check specifically for a file
if (Test-Path -Path "C:\file.txt" -PathType Leaf) {
    Write-Output "File exists"
}

# Check specifically for a folder
if (Test-Path -Path "C:\Temp" -PathType Container) {
    Write-Output "Folder exists"
}

Short Circuit Evaluation

# PowerShell evaluates left to right and stops when result is known
if (($null -ne $user) -and ($user.IsActive -eq $true)) {
    # If $user is null, second condition never runs (avoiding error)
}

# Put the "cheapest" check first for performance
if (($item.Length -gt 0) -and ($item.Name -like "*.log")) {
    # Length check is faster than string comparison
}

Ternary Operator (PowerShell 7+)

# Modern PowerShell has a ternary operator for simple if/else
$status = ($diskSpace -lt 20) ? "Low" : "OK"

# Same as:
if ($diskSpace -lt 20) {
    $status = "Low"
} else {
    $status = "OK"
}

Don't Use Assignment in Conditions

# This is ALWAYS true (assignment returns the assigned value)
if ($result = Get-Process) {  # Assigns AND checks
    # This runs if Get-Process returns anything
}

# Be explicit about what you want
$result = Get-Process
if ($null -ne $result) {
    # Clear intent
}

Remember Case Insensitivity

# These are EQUAL by default
"PowerShell" -eq "powershell"  # $true

# Use -ceq for case-sensitive comparison
"PowerShell" -ceq "powershell"  # $false

# Same for -like, -match, etc.
"Test" -like "test"    # $true (case-insensitive)
"Test" -clike "test"   # $false (case-sensitive)

Array Contains vs In

$colors = "Red", "Green", "Blue"

# These are equivalent but reversed
$colors -contains "Red"     # $true (array -contains value)
"Red" -in $colors           # $true (value -in array)

# Choose based on readability
if ($allowedUsers -contains $currentUser) { }  # Check if user is allowed
if ($currentUser -in $allowedUsers) { }        # Same thing, different phrasing

Additional Resources