Skip to content

PowerShell Relational Operators

How PowerShell's text-based comparison operators (-eq, -ne, -gt, -lt) work with scalars, collections, and case sensitivity, plus wildcard (-like) and regex (-match) filtering.

Relational operators (also known as comparison operators) compare two or more values, test strings against pattern rules, and filter arrays. Unlike languages that use symbolic notation (such as ==, !=, <, >), PowerShell uses hyphenated text tokens (-eq, -ne, -gt, -lt). When applied to scalar values, these operators return a boolean ($true or $false). When applied to collections, they act as high-speed data filters, returning all matching elements.

Equality and Comparison Operators

PowerShell provides six primary numeric and structural comparison operators:

Operator Meaning Example Expression Scalar Result
-eq Equal to 10 -eq 10 $true
-ne Not equal to 10 -ne 20 $true
-gt Greater than 15 -gt 10 $true
-ge Greater than or equal to 10 -ge 10 $true
-lt Less than 5 -lt 10 $true
-le Less than or equal to 10 -le 10 $true
scalar-comparison.ps1powershell
$ServicePort = 8080
$MaxAllowedPort = 1024

[PSCustomObject]@{
    IsPrivilegedPort = ($ServicePort -le $MaxAllowedPort)
    IsStandardHttp   = ($ServicePort -eq 80)
    IsCustomPort     = ($ServicePort -gt $MaxAllowedPort)
}
Consolepowershell
pwsh ./scalar-comparison.ps1
Outputplaintext
IsPrivilegedPort IsStandardHttp IsCustomPort
---------------- -------------- ------------
           False          False         True

Collection Filtering Behavior

When the left-hand operand of a comparison operator is an array or collection, PowerShell changes its behavior. Instead of returning a single boolean $true or $false, it returns an array containing only the elements that satisfy the condition:

Consolepowershell
$Numbers = 10, 20, 30, 40, 50
$Numbers -gt 25

$Names = "web01", "sql01", "app01", "sql02"
$Names -like "sql*"
Outputplaintext
30
40
50
sql01
sql02

Case Sensitivity: Prefix Modifiers (c vs. i)

By default, all relational operators in PowerShell are case-insensitive. For example, "powershell" -eq "POWERSHELL" evaluates to $true.

To explicitly declare or override case behavior, prefix the operator with either i (case-insensitive, default) or c (case-sensitive):

Case-Insensitive (Default) Case-Sensitive Example Expression Result
-eq or -ieq -ceq "Admin" -ceq "admin" $false
-ne or -ine -cne "Admin" -cne "admin" $true
-like or -ilike -clike "Test" -clike "t*" $false
-match or -imatch -cmatch "Prod" -cmatch "[A-Z]{4}" $false
Consolepowershell
"System Administrator" -match "admin"

"System Administrator" -cmatch "admin"
Outputplaintext
True
False

Wildcard Matching: -like and -notlike

The -like and -notlike operators evaluate string expressions using standard PowerShell wildcard patterns, similar to file system searches.

Supported Wildcard Characters

Wildcard Description Example Pattern Matches
* Matches zero or more arbitrary characters "web-prod-01" -like "web*" $true
? Matches exactly one single character "disk1" -like "disk?" $true
[abc] Matches any single character within the enclosed set "logB" -like "log[AB]" $true
[a-z] Matches any single character within the specified ASCII range "core3" -like "core[0-9]" $true
wildcard-matching.ps1powershell
$LogFileA = "system-audit-2026.log"
$LogFileB = "temp-cache.tmp"

[PSCustomObject]@{
    IsAuditFile = ($LogFileA -like "system-*-2026.???")
    IsLogFormat = ($LogFileA -like "*.log")
    IsExcluded  = ($LogFileB -notlike "*.log")
}
Consolepowershell
pwsh ./wildcard-matching.ps1
Outputplaintext
IsAuditFile IsLogFormat IsExcluded
----------- ----------- ----------
       True        True       True

where:

  • "*.csv" matches any string ending in .csv, regardless of what precedes it.
  • "report_????.csv" matches exactly four characters between report_ and .csv.
  • -notlike returns $true when the pattern does not match.

Regular Expression Matching: -match and -notmatch

The -match and -notmatch operators evaluate string data against .NET regular expressions (regex). Unlike -like (which requires wildcards to match the entire string from start to finish), -match succeeds if the regular expression pattern matches any substring within the target text, unless explicitly anchored with ^ (start) or $ (end).

Consolepowershell
"user@example.com" -match "^\w+@\w+\.\w+$"
"12345" -match "^\d+$"
"abc123" -notmatch "^\d+$"
Outputplaintext
True
True
True

where:

  • ^\w+@\w+\.\w+$ validates a simple email-like pattern using regex anchors (^, $) and character classes (\w, \d).
  • -notmatch returns $true when the pattern does not match the string.

The $Matches Automatic Variable

When -match evaluates to $true on a scalar string, PowerShell automatically populates the $Matches automatic variable with a hashtable containing the full matched text (at key 0) and any extracted capture groups:

regex-capture.ps1powershell
$LogEntry = "2026-10-24 14:32:00 [CRITICAL] Database node SQL-PROD-02 connection timeout."

$Pattern = '\[(?<Severity>[A-Z]+)\] Database node (?<NodeName>[A-Z0-9-]+)'

if ($LogEntry -match $Pattern) {
    [PSCustomObject]@{
        SeverityLevel = $Matches['Severity']
        ImpactedNode  = $Matches['NodeName']
        FullMatchText = $Matches[0]
    }
}

where:

  • \[ escapes literal brackets.
  • (?<Severity>[A-Z]+) creates a named capture group matching consecutive uppercase letters.
  • (?<NodeName>[A-Z0-9-]+) creates a named capture group matching alphanumeric hostnames.
  • $Matches['Severity'] retrieves the captured data from the automatic hashtable.
Consolepowershell
pwsh ./regex-capture.ps1
Outputplaintext
SeverityLevel ImpactedNode FullMatchText
------------- ------------ -------------
CRITICAL      SQL-PROD-02  [CRITICAL] Database node SQL-PROD-02

Positional Capture Groups

You can also use positional capture groups with parentheses:

Consolepowershell
"Order-2026-0091" -match "Order-(\d+)-(\d+)"
$matches[0]
$matches[1]
$matches[2]
Outputplaintext
True
Order-2026-0091
2026
0091

where:

  • $matches[0] contains the entire matched string.
  • $matches[1] and $matches[2] contain the values captured by each parenthesized group (\d+) in order.

Choosing the Right Operator

Scenario Recommended Operator
Comparing numbers or exact strings -eq, -ne, -gt, -lt, -ge, -le
Simple filename or basic pattern checks -like, -notlike
Complex pattern validation or extraction -match, -notmatch

Practical Example: Automated System Process and Security Audit

The following script inspects active processes, using numeric comparison operators to identify high-memory consumers, wildcard matching to locate system services, and regular expressions to parse command-line metadata:

audit-process-workload.ps1powershell
param (
    [double]$MemoryThresholdMB = 200.0
)

$HighMemoryProcesses = Get-Process | Where-Object { 
    ($_.WorkingSet64 / 1MB) -ge $MemoryThresholdMB 
}

$AuditReport = foreach ($proc in $HighMemoryProcesses) {
    $procName = $proc.ProcessName
    $memoryMB = [math]::Round($proc.WorkingSet64 / 1MB, 2)

    $isHostWorker = ($procName -like "*host*" -or $procName -like "*worker*")

    $workloadCategory = switch -Regex ($procName) {
        "^(chrome|msedge|firefox)$" { "Web Browser" }
        "^(code|devenv|rider)$"     { "Development IDE" }
        "^sql|mongod|postgres"      { "Database Engine" }
        Default                     { "System/Background Task" }
    }

    [PSCustomObject]@{
        PID              = $proc.Id
        ProcessName      = $procName
        MemoryUsageMB    = $memoryMB
        ExceedsCritical  = ($memoryMB -gt 1000.0)
        IsHostWorker     = $isHostWorker
        Category         = $workloadCategory
    }
}

$AuditReport | Sort-Object -Property MemoryUsageMB -Descending | Select-Object -First 2

where:

  • ($_.WorkingSet64 / 1MB) -ge $MemoryThresholdMB uses -ge to filter numeric memory values.
  • ($procName -like "*host*") uses wildcards to identify background hosts.
  • switch -Regex ($procName) matches process names against regular expression patterns (^, $, |).
  • ($memoryMB -gt 1000.0) uses -gt to flag memory usage exceeding 1 GB.

Execute the script from the console:

Consolepowershell
pwsh ./audit-process-workload.ps1 -MemoryThresholdMB 150.0
Outputplaintext
PID             : 1300
ProcessName     : Memory Compression
MemoryUsageMB   : 207.73
ExceedsCritical : False
IsHostWorker    : False
Category        : System/Background Task

PID             : 6184
ProcessName     : explorer
MemoryUsageMB   : 201.44
ExceedsCritical : False
IsHostWorker    : False
Category        : System/Background Task
Navigation