By Davy Rogers. Use these techniques only in environments you own or have explicit permission to test.

PowerShell: If Statements and Conditionals

Conditional statements allow your scripts to make decisions based on conditions. PowerShell provides if, elseif, else, and switch statements for control flow. This lesson covers all conditional constructs with practical pentesting examples.

What You'll Learn

  • if, elseif, else statements
  • Comparison operators
  • Logical operators
  • switch statement
  • Ternary operator (PowerShell 7+)
  • Testing conditions
  • Practical decision-making scenarios

if Statement

Basic Syntax

if (condition) {
    # Code to execute if true
}

Examples

# Simple if
$age = 25
if ($age -ge 18) {
    Write-Host "You are an adult"
}

# Test file existence
if (Test-Path "file.txt") {
    Write-Host "File exists"
}

# Check service status
$service = Get-Service -Name wuauserv
if ($service.Status -eq "Running") {
    Write-Host "Service is running"
}

if-else Statement

Syntax

if (condition) {
    # Code if true
} else {
    # Code if false
}

Examples

# Basic if-else
$age = 15
if ($age -ge 18) {
    Write-Host "You are an adult"
} else {
    Write-Host "You are a minor"
}

# Check process
$process = Get-Process notepad -ErrorAction SilentlyContinue
if ($process) {
    Write-Host "Notepad is running"
} else {
    Write-Host "Notepad is not running"
}

# Ping check
if (Test-Connection -ComputerName "google.com" -Count 1 -Quiet) {
    Write-Host "Internet is available"
} else {
    Write-Host "No internet connection"
}

if-elseif-else Statement

Syntax

if (condition1) {
    # Code if condition1 is true
} elseif (condition2) {
    # Code if condition2 is true
} elseif (condition3) {
    # Code if condition3 is true
} else {
    # Code if all conditions are false
}

Examples

# Age categories
$age = 30
if ($age -lt 13) {
    Write-Host "Child"
} elseif ($age -lt 18) {
    Write-Host "Teenager"
} elseif ($age -lt 65) {
    Write-Host "Adult"
} else {
    Write-Host "Senior"
}

# File size categories
$file = Get-Item "file.txt"
if ($file.Length -lt 1KB) {
    Write-Host "Small file"
} elseif ($file.Length -lt 1MB) {
    Write-Host "Medium file"
} elseif ($file.Length -lt 1GB) {
    Write-Host "Large file"
} else {
    Write-Host "Huge file"
}

# Port status
$port = 80
if ($port -eq 80) {
    Write-Host "HTTP"
} elseif ($port -eq 443) {
    Write-Host "HTTPS"
} elseif ($port -eq 22) {
    Write-Host "SSH"
} else {
    Write-Host "Unknown port"
}

Comparison Operators

Numeric Comparisons

-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
5 -ne 10    # True
10 -gt 5    # True
10 -ge 10   # True
5 -lt 10    # True
5 -le 5     # True

String Comparisons

-eq     # Equal (case-insensitive)
-ceq    # Equal (case-sensitive)
-ne     # Not equal
-like   # Wildcard match
-notlike # Wildcard not match
-match  # Regex match
-notmatch # Regex not match

Examples:

# Case-insensitive by default
"hello" -eq "HELLO"        # True
"hello" -ceq "HELLO"       # False (case-sensitive)

# Wildcards
"PowerShell" -like "Power*"    # True
"PowerShell" -notlike "Bash*"  # True

# Regex
"abc123" -match "\d+"          # True
"PowerShell" -notmatch "\d+"   # True

Collection Comparisons

-contains    # Collection contains value
-notcontains # Collection doesn't contain value
-in          # Value in collection
-notin       # Value not in collection

Examples:

$array = @(1, 2, 3, 4, 5)

# Contains
$array -contains 3         # True
$array -notcontains 10     # True

# In
3 -in $array              # True
10 -notin $array          # True

Logical Operators

AND, OR, NOT

-and    # Logical AND
-or     # Logical OR
-not    # Logical NOT
!       # Logical NOT (alternative)

Examples:

# AND
if ($age -ge 18 -and $age -lt 65) {
    Write-Host "Working age adult"
}

# OR
if ($user -eq "admin" -or $user -eq "root") {
    Write-Host "Privileged user"
}

# NOT
if (-not (Test-Path "file.txt")) {
    Write-Host "File doesn't exist"
}

# Alternative NOT
if (!(Test-Path "file.txt")) {
    Write-Host "File doesn't exist"
}

# Complex conditions
if (($age -ge 18) -and ($country -eq "USA" -or $country -eq "Canada")) {
    Write-Host "Eligible"
}

Type Testing

-is     # Is of type
-isnot  # Is not of type

Examples:

$var = 42

if ($var -is [int]) {
    Write-Host "Variable is an integer"
}

if ($var -isnot [string]) {
    Write-Host "Variable is not a string"
}

# Check for null
if ($null -eq $var) {
    Write-Host "Variable is null"
}

switch Statement

Basic Syntax

switch (expression) {
    value1 { # Code }
    value2 { # Code }
    default { # Code }
}

Examples:

# Simple switch
$day = "Monday"
switch ($day) {
    "Monday"    { Write-Host "Start of week" }
    "Friday"    { Write-Host "End of week" }
    "Saturday"  { Write-Host "Weekend!" }
    "Sunday"    { Write-Host "Weekend!" }
    default     { Write-Host "Midweek" }
}

# Multiple matches
$color = "red"
switch ($color) {
    "red"   { Write-Host "Stop" }
    "yellow" { Write-Host "Caution" }
    "green" { Write-Host "Go" }
}

# With -Wildcard
$filename = "document.txt"
switch -Wildcard ($filename) {
    "*.txt"  { Write-Host "Text file" }
    "*.pdf"  { Write-Host "PDF file" }
    "*.exe"  { Write-Host "Executable" }
    default  { Write-Host "Unknown type" }
}

# With -Regex
$input = "abc123"
switch -Regex ($input) {
    "^\d+$"        { Write-Host "All digits" }
    "^[a-z]+$"     { Write-Host "All letters" }
    "[a-z]+\d+"    { Write-Host "Mixed alphanumeric" }
}

switch on Collections

# Process multiple values
$numbers = 1, 2, 3, 4, 5
switch ($numbers) {
    1 { Write-Host "One" }
    2 { Write-Host "Two" }
    3 { Write-Host "Three" }
    default { Write-Host "Other: $_" }
}

Ternary Operator (PowerShell 7+)

Syntax

condition ? value_if_true : value_if_false

Examples:

# Simple ternary
$age = 20
$status = $age -ge 18 ? "Adult" : "Minor"

# Nested ternary
$score = 85
$grade = $score -ge 90 ? "A" : ($score -ge 80 ? "B" : "C")

# With assignment
$result = (Test-Path "file.txt") ? "Exists" : "Not found"

Practical Examples

Example 1: User Permission Check

$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)

if ($principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host "Running as Administrator" -ForegroundColor Green
} else {
    Write-Host "NOT running as Administrator" -ForegroundColor Red
}

Example 2: Disk Space Warning

$disk = Get-PSDrive C
$freeSpaceGB = [math]::Round($disk.Free / 1GB, 2)
$usedPercent = [math]::Round((($disk.Used / ($disk.Used + $disk.Free)) * 100), 2)

if ($usedPercent -gt 90) {
    Write-Host "CRITICAL: Disk is $usedPercent% full" -ForegroundColor Red
} elseif ($usedPercent -gt 80) {
    Write-Host "WARNING: Disk is $usedPercent% full" -ForegroundColor Yellow
} else {
    Write-Host "OK: Disk is $usedPercent% full" -ForegroundColor Green
}

Example 3: Service Management

$serviceName = "wuauserv"
$service = Get-Service -Name $serviceName

if ($service.Status -eq "Running") {
    Write-Host "$serviceName is already running"
} else {
    Write-Host "Starting $serviceName..."
    Start-Service -Name $serviceName
    
    if ((Get-Service -Name $serviceName).Status -eq "Running") {
        Write-Host "Service started successfully"
    } else {
        Write-Host "Failed to start service"
    }
}

Example 4: Backup Decision

$sourceFile = "important.txt"
$backupFile = "important_backup.txt"

if (Test-Path $sourceFile) {
    if (Test-Path $backupFile) {
        $source = Get-Item $sourceFile
        $backup = Get-Item $backupFile
        
        if ($source.LastWriteTime -gt $backup.LastWriteTime) {
            Write-Host "Source is newer, creating backup..."
            Copy-Item $sourceFile $backupFile -Force
        } else {
            Write-Host "Backup is up to date"
        }
    } else {
        Write-Host "No backup exists, creating..."
        Copy-Item $sourceFile $backupFile
    }
} else {
    Write-Host "Source file not found!"
}

Practical Pentesting Scenarios

Scenario 1: Port Check and Action

$target = "192.168.1.1"
$port = 445

$connection = Test-NetConnection -ComputerName $target -Port $port -WarningAction SilentlyContinue

if ($connection.TcpTestSucceeded) {
    Write-Host "[+] Port $port is OPEN on $target" -ForegroundColor Green
    Write-Host "[*] Attempting SMB enumeration..."
    # Run SMB enumeration commands
} else {
    Write-Host "[-] Port $port is CLOSED on $target" -ForegroundColor Red
}

Scenario 2: Credential Validation

$username = "admin"
$password = "password123"

try {
    $secPass = ConvertTo-SecureString $password -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential($username, $secPass)
    
    # Test credential
    $result = Invoke-Command -ComputerName $target -Credential $cred -ScriptBlock { hostname } -ErrorAction Stop
    
    if ($result) {
        Write-Host "[+] Valid credentials: $username:$password" -ForegroundColor Green
    }
} catch {
    Write-Host "[-] Invalid credentials" -ForegroundColor Red
}

Scenario 3: File Type Analysis

$file = Get-Item "suspicious.file"

switch ($file.Extension) {
    ".exe" {
        Write-Host "[!] Executable file detected" -ForegroundColor Yellow
        $hash = (Get-FileHash $file.FullName -Algorithm SHA256).Hash
        Write-Host "SHA256: $hash"
    }
    ".ps1" {
        Write-Host "[!] PowerShell script detected" -ForegroundColor Yellow
        $content = Get-Content $file.FullName
        if ($content -match "Invoke-Expression|IEX|DownloadString") {
            Write-Host "[!] Suspicious PowerShell commands found!" -ForegroundColor Red
        }
    }
    ".dll" {
        Write-Host "[!] DLL file detected" -ForegroundColor Yellow
    }
    default {
        Write-Host "[*] Unknown file type: $($file.Extension)"
    }
}

Scenario 4: Privilege Escalation Check

# Check for unquoted service paths
$services = Get-WmiObject Win32_Service | Where-Object {
    $_.PathName -notmatch '^"' -and $_.PathName -match ' '
}

if ($services) {
    Write-Host "[+] Found services with unquoted paths:" -ForegroundColor Green
    foreach ($service in $services) {
        Write-Host "  - $($service.Name): $($service.PathName)"
    }
} else {
    Write-Host "[-] No unquoted service paths found"
}

# Check for writable service binaries
$services = Get-Service
foreach ($service in $services) {
    $path = (Get-WmiObject Win32_Service -Filter "Name='$($service.Name)'").PathName
    if ($path -and (Test-Path $path)) {
        try {
            [System.IO.File]::OpenWrite($path).Close()
            Write-Host "[+] Writable service: $($service.Name) at $path" -ForegroundColor Green
        } catch {
            # Not writable
        }
    }
}

Scenario 5: Network Reachability Decision

$targets = @("192.168.1.1", "192.168.1.100", "192.168.1.200")

foreach ($target in $targets) {
    if (Test-Connection -ComputerName $target -Count 1 -Quiet) {
        Write-Host "[+] $target is UP" -ForegroundColor Green
        
        # Check common ports
        $http = Test-NetConnection -ComputerName $target -Port 80 -WarningAction SilentlyContinue
        $https = Test-NetConnection -ComputerName $target -Port 443 -WarningAction SilentlyContinue
        $smb = Test-NetConnection -ComputerName $target -Port 445 -WarningAction SilentlyContinue
        
        if ($http.TcpTestSucceeded) { Write-Host "    HTTP (80) is open" }
        if ($https.TcpTestSucceeded) { Write-Host "    HTTPS (443) is open" }
        if ($smb.TcpTestSucceeded) { Write-Host "    SMB (445) is open" }
    } else {
        Write-Host "[-] $target is DOWN" -ForegroundColor Red
    }
}

Quick Reference

if Statement:
if (condition) { }
if (condition) { } else { }
if (cond1) { } elseif (cond2) { } else { }

Comparison:
-eq, -ne, -gt, -ge, -lt, -le    # Numeric/string
-like, -notlike                  # Wildcard
-match, -notmatch                # Regex
-contains, -notcontains          # Collection
-in, -notin                      # Membership

Logical:
-and, -or, -not, !

Type Testing:
-is, -isnot

switch Statement:
switch ($var) {
    value1 { }
    value2 { }
    default { }
}

switch -Wildcard ($var) { "pattern*" { } }
switch -Regex ($var) { "^\d+$" { } }

Ternary (PS 7+):
$result = condition ? true_value : false_value

Common Pitfalls

1. Using = Instead of -eq

# Wrong (assignment)
if ($x = 5) { }

# Right (comparison)
if ($x -eq 5) { }

2. String Comparison Case Sensitivity

# Case-insensitive (default)
"hello" -eq "HELLO"   # True

# Use -ceq for case-sensitive
"hello" -ceq "HELLO"  # False

3. Testing for $null

# Right
if ($null -eq $var) { }

# Wrong (might not work as expected)
if ($var -eq $null) { }

Resources

Help

Get-Help about_If
Get-Help about_Switch
Get-Help about_Comparison_Operators
Get-Help about_Logical_Operators

Next Steps

  1. Practice conditions in every script
  2. Master comparison operators (-eq, -like, -match)
  3. Use switch for multiple conditions
  4. Learn ternary operator (PowerShell 7+)
  5. Combine with loops for powerful automation

Conditionals give your scripts intelligence. Master them and your scripts will make smart decisions!


"if statements: Where scripts learn to think for themselves."