PowerShell provides a rich set of comparison operators that are essential for decision-making in scripts. These operators allow you to compare values, filter data, and create conditional logic that makes your scripts more intelligent and responsive. In this guide, we’ll explore the most commonly used comparison operators and see them in action.
What are Comparison Operators?
Comparison operators in PowerShell are special symbols or keywords that compare two values and return a Boolean result (`$true` or `$false`). They are case-insensitive by default, but PowerShell also provides case-sensitive variants for when you need precise string matching.
Basic Comparison Operators
Here are the fundamental comparison operators you’ll use most often:
-eq
: Equal to-ne
: Not equal to-lt
: Less than-le
: Less than or equal to-gt
: Greater than-ge
: Greater than or equal to
Equality Operators (-eq and -ne)
The equality operators are the most commonly used comparison operators. Here’s a few basic examples:
$name = "PowerShell"
$version = 7
# Check if values are equal
$name -eq "PowerShell" # Returns $true
$version -eq 5 # Returns $false
# Check if values are not equal
$name -ne "Bash" # Returns $true
$version -ne 7 # Returns $false
Numerical Comparison Operators
These operators work with numbers and can also be used with strings (alphabetical comparison).
$score1 = 85
$score2 = 92
$score1 -lt $score2 # Less than: $true
$score1 -le 85 # Less than or equal: $true
$score2 -gt $score1 # Greater than: $true
$score2 -ge 92 # Greater than or equal: $true
# String comparisons (alphabetical)
"apple" -lt "banana" # $true
"zebra" -gt "apple" # $true
Case-Sensitive Operators
By default, PowerShell comparison operators are case-insensitive. For case-sensitive comparisons, use the ‘c’ prefix:
-ceq
: Case-sensitive equal-cne
: Case-sensitive not equal-clt
: Case-sensitive less than-cle
: Case-sensitive less than or equal-cgt
: Case-sensitive greater than-cge
: Case-sensitive greater than or equal
Here’s a few examples to demonstrate the difference:
$text = "PowerShell"
# Case-insensitive (default)
$text -eq "powershell" # $true
$text -eq "POWERSHELL" # $true
# Case-sensitive
$text -ceq "powershell" # $false
$text -ceq "PowerShell" # $true
Pattern Matching Operators
PowerShell also includes operators for pattern matching:
-like
: Wildcard matching-notlike
: Negated wildcard matching-match
: Regular expression matching-notmatch
: Negated regular expression matching
Try it with these examples:
# Wildcard matching with -like
$filename = "report.txt"
$filename -like "*.txt" # $true
$filename -like "report.*" # $true
$filename -notlike "*.pdf" # $true
# Regular expression matching
$email = "user@example.com"
$email -match "\w+@\w+\.\w+" # $true (basic email pattern)
# Check if a string contains digits
"PowerShell7" -match "\d" # $true
"PowerShell" -match "\d" # $false
Container Operators
These operators work with collections and arrays:
-contains
: Check if a collection contains a specific item-notcontains
: Check if a collection does not contain a specific item-in
: Check if an item exists in a collection-notin
: Check if an item does not exist in a collection
Test them with different array’s such as these examples:
# Working with arrays and collections
$fruits = @("apple", "banana", "cherry", "date")
$numbers = 1..10
# Check if collection contains an item
$fruits -contains "banana" # $true
$fruits -notcontains "grape" # $true
# Check if item is in collection
"cherry" -in $fruits # $true
"grape" -notin $fruits # $true
# Works with numbers too
5 -in $numbers # $true
15 -notin $numbers # $true
Practical Examples in Decision Making
Let me give you some practical real-world scenarios!
function Test-FileExtension {
param($FilePath, $AllowedExtensions)
$extension = [System.IO.Path]::GetExtension($FilePath)
if ($extension -in $AllowedExtensions) {
Write-Output "File extension '$extension' is allowed"
return $true
} else {
Write-Output "File extension '$extension' is not allowed"
return $false
}
}
# Test the function
$allowedExts = @(".txt", ".docx", ".pdf")
Test-FileExtension -FilePath "document.pdf" -AllowedExtensions $allowedExts
Test-FileExtension -FilePath "script.ps1" -AllowedExtensions $allowedExts
function Test-PasswordStrength {
param([string]$Password)
$score = 0
$feedback = @()
if ($Password.Length -ge 8) {
$score++
$feedback += "Length is adequate (8+ characters)"
} else {
$feedback += "Password too short (needs 8+ characters)"
}
if ($Password -match "[A-Z]") {
$score++
$feedback += "Contains uppercase letters"
} else {
$feedback += "Needs uppercase letters"
}
if ($Password -match "[0-9]") {
$score++
$feedback += "Contains numbers"
} else {
$feedback += "Needs numbers"
}
if ($Password -match "[^a-zA-Z0-9]") {
$score++
$feedback += "Contains special characters"
} else {
$feedback += "Needs special characters"
}
$feedback | ForEach-Object { Write-Output $_ }
if ($score -ge 3) {
Write-Output "Password strength: GOOD"
} else {
Write-Output "Password strength: WEAK"
}
}
# Test password strength
Test-PasswordStrength -Password "MyP@ssw0rd"
function Test-SystemResources {
# Simulate getting system metrics
$cpuUsage = Get-Random -Minimum 10 -Maximum 95
$memoryUsage = Get-Random -Minimum 20 -Maximum 90
$diskSpace = Get-Random -Minimum 5 -Maximum 95
Write-Output "System Resource Check:"
Write-Output "====================="
# CPU Usage Check
if ($cpuUsage -lt 50) {
Write-Output "CPU Usage: $cpuUsage% (Normal)"
} elseif ($cpuUsage -le 80) {
Write-Output "CPU Usage: $cpuUsage% (Warning)"
} else {
Write-Output "CPU Usage: $cpuUsage% (Critical)"
}
# Memory Usage Check
if ($memoryUsage -lt 60) {
Write-Output "Memory Usage: $memoryUsage% (Normal)"
} elseif ($memoryUsage -le 85) {
Write-Output "Memory Usage: $memoryUsage% (Warning)"
} else {
Write-Output "Memory Usage: $memoryUsage% (Critical)"
}
# Disk Space Check
if ($diskSpace -gt 20) {
Write-Output "Free Disk Space: $diskSpace% (Normal)"
} elseif ($diskSpace -ge 10) {
Write-Output "Free Disk Space: $diskSpace% (Warning)"
} else {
Write-Output "Free Disk Space: $diskSpace% (Critical)"
}
}
# Run system check
Test-SystemResources
Filtering Collections with Comparison Operators
One of the most powerful uses of comparison operators is filtering collections using the Where-Object
cmdlet.
$employees = @(
@{Name="Alice"; Department="IT"; Salary=75000; Years=3}
@{Name="Bob"; Department="HR"; Salary=65000; Years=5}
@{Name="Charlie"; Department="IT"; Salary=85000; Years=7}
@{Name="Diana"; Department="Finance"; Salary=70000; Years=2}
@{Name="Eve"; Department="IT"; Salary=90000; Years=8}
)
# Filter examples using comparison operators
Write-Output "IT Department employees:"
$employees | Where-Object {$_.Department -eq "IT"} | ForEach-Object {$_.Name}
Write-Output "Employees with salary > 70000:"
$employees | Where-Object {$_.Salary -gt 70000} | ForEach-Object {"$($_.Name): $($_.Salary)"}
Write-Output "Senior employees (5+ years):"
$employees | Where-Object {$_.Years -ge 5} | ForEach-Object {"$($_.Name): $($_.Years) years"}
Write-Output "Employees NOT in Finance:"
$employees | Where-Object {$_.Department -ne "Finance"} | ForEach-Object {$_.Name}
Things to be aware of
PowerShell automatically converts types when comparing. Be aware of this behavior. This is known as Type Coersion. Below is a short example of how this works, in a future blog we will take a closer look at how this works.
"5" -eq 5 # $true (string converted to number)
"05" -eq 5 # $true (leading zero ignored)
"5.0" -eq 5 # $true (decimal converted to integer)
# To avoid type coercion, ensure both sides are the same type
[string]"5" -eq [string]5 # $false (both are strings now)
One other thing to be aware of is “Null Value Handling”. Jos has written a great article about that here.
Conclusion
PowerShell’s comparison operators are fundamental tools for creating intelligent scripts. Whether you’re filtering data, validating input, or making decisions based on system conditions, these operators provide the foundation for robust script logic. If you want to read more interesting things about operators be sure to read Jos’s article on Coalescing in PowerShell 7!
Leave a Reply