switch: Values, Wildcards, Regex, Files, and Multiple Matches
Classify values, collections, and line-oriented input with PowerShell switch, choose exact/wildcard/regex matching intentionally, and control overlapping matches safely.
Learning objectives
- Explain how PowerShell switch differs from a first-match-only C-style mental model.
- Use exact/default, wildcard, regex, and case-sensitive matching according to the data contract.
- Process collection input one element at a time and understand the current $_/$PSItem value.
- Distinguish break from continue when switch processes multiple input items.
- Use switch -File safely for line-oriented training data and regex captures only where justified.
- Choose a lookup hashtable instead of switch when the requirement is simple key-to-value data mapping.
1. switch is a matcher over values, not only a prettier
if chain
Use if when each branch is naturally a Boolean rule.
Use switch when one or more input values should be
compared against a set of cases. PowerShell goes beyond the C-style
“pick exactly one case” mental model: one input can match multiple
clauses unless you deliberately stop processing.
$state = 'warning'
switch ($state) {
'ok' { 'No action required.' }
'warning' { 'Investigate soon.' }
'error' { 'Immediate attention required.' }
default { 'Unknown state.' }
}
Without mode switches, string matching is exact and
case-insensitive. For ordinary case-value comparison, PowerShell
converts values to strings before comparing them; use script-block
conditions when the object type itself must drive the decision. The
default clause runs only when no earlier case matches
the current input value.
2. PowerShell tests every matching clause unless
break or continue changes the flow
A single input can trigger multiple actions. This is useful when classifications overlap, but it surprises learners who assume the first match wins.
switch ('warning') {
{ $_ -is [string] } { "String input: $_" }
'warning' { "Severity match: $_" }
}
String input: warning
Severity match: warning
Both clauses match. If exactly one action should run, place
break or continue intentionally after the
selected action, depending on whether the switch is processing one
value or a collection.
3. Exact, wildcard, regex, and case sensitivity are different matching contracts
| Mode | Example | Mental model |
|---|---|---|
Default / -Exact |
'error' |
Whole value must match; string comparison is case-insensitive unless requested otherwise. |
-CaseSensitive |
'ERROR' does not equal 'error'
|
Letter case becomes significant. |
-Wildcard |
'error*' |
Shell-style patterns such as * and
?.
|
-Regex |
'^ERR\d+$' |
Regular-expression pattern matching;
$Matches is available on a match.
|
$message = 'ERROR disk pressure'
switch -Wildcard ($message) {
'ERROR*' { 'Error-class message' }
'*pressure*' { 'Capacity-related message' }
}
This produces two classifications because both wildcard patterns match. That is often exactly what log enrichment needs.
4. A collection input is processed one element at a time
When the switch input is a collection, PowerShell evaluates every
element in order. Inside a matching action, $_ or
$PSItem is the current input element.
$states = 'ok', 'warning', 'error', 'ok'
switch ($states) {
'ok' { "OK: $_" }
'warning' { "WARN: $_" }
'error' { "ERROR: $_" }
}
This makes switch useful for classifying lists without
writing a separate outer loop. Still, if the transformation is
primarily a pipeline operation, ForEach-Object may be
clearer; Lesson 03 compares those iteration styles.
5. In collection switches, break exits the whole
switch; continue moves to the next input item
The difference matters most when input contains many values.
break stops the entire switch immediately.
continue stops testing additional clauses for the
current item and advances to the next item.
$messages = @(
'INFO starting service'
'WARN disk at 80%'
'ERROR disk at 95%'
'INFO this line is never reached with break'
)
switch -Wildcard ($messages) {
'ERROR*' {
"Critical: $_"
break
}
'WARN*' {
"Warning: $_"
continue
}
default {
"Other: $_"
}
}
The warning action uses continue so the next message is
still processed. The error action uses break, so later
input is not examined. Choose this intentionally; an accidental
break can suppress evidence from later records.
6. Regex mode gives captures through $Matches
Regular expressions are powerful when input has a consistent textual structure. Keep the first regex small and anchored so learners can see what it means. Here a log line begins with a severity token followed by a colon and message text.
$line = 'WARN: cache usage 82%'
switch -Regex ($line) {
'^(INFO|WARN|ERROR):\s+(?<Message>.+)$' {
[pscustomobject]@{
Severity = $Matches[1]
Message = $Matches['Message']
}
break
}
default {
[pscustomobject]@{ Severity='UNKNOWN'; Message=$_ }
}
}
The match populates $Matches. Index
1 contains the first capture group; the named group
Message is available by name. Do not reach for regex
when exact or wildcard matching expresses the rule more clearly.
7. switch -File can classify a text file one line at a
time
The -File form reads one file line by line and applies
the switch rules to each line. This is useful for line-oriented
logs. Because it is a filename argument, wildcard characters in the
path can have meaning; use a literal-safe path strategy when
filenames can contain wildcard characters.
$path = Join-Path ([System.IO.Path]::GetTempPath()) 'ps-academy-switch.log'
@(
'INFO startup complete'
'WARN queue depth high'
'ERROR dependency unavailable'
) | Set-Content -LiteralPath $path -Encoding utf8
try {
switch -Wildcard -File $path {
'ERROR*' { "ERROR => $_"; continue }
'WARN*' { "WARN => $_"; continue }
default { "INFO => $_" }
}
}
finally {
Remove-Item -LiteralPath $path -Force -ErrorAction SilentlyContinue
}
The temporary file makes the example reproducible without touching system logs. Chapter 07 will teach path and file handling in depth.
8. A lookup hashtable is better when the relationship is simple data
If every input key maps directly to one value and there is no
branching logic, a hashtable is usually simpler than
switch.
$portByService = @{
api = 8443
metrics = 9090
cache = 6379
}
$portByService['metrics']
Use switch when matching modes, overlapping rules,
conditional action blocks, or line-by-line classification are
central. Use a hashtable when you mean “key X maps to value Y.”
9. Lab: classify operational log lines with layered rules
This lab demonstrates collection input, wildcard matching, regex
extraction, multiple possible matches, and deliberate
continue. It produces structured objects so later
stages can filter or export them.
$lines = @(
'INFO service=api status=ready'
'WARN service=cache usage=82%'
'ERROR service=db code=503 message=upstream unavailable'
'DEBUG service=api detail=probe'
)
$classified = switch -Regex ($lines) {
'^INFO\s+service=(?<Service>\S+)\s+status=(?<Status>\S+)$' {
[pscustomobject]@{ Level='INFO'; Service=$Matches.Service; Detail=$Matches.Status }
continue
}
'^WARN\s+service=(?<Service>\S+)\s+usage=(?<Usage>\d+)%$' {
[pscustomobject]@{ Level='WARN'; Service=$Matches.Service; Detail="Usage $($Matches.Usage)%" }
continue
}
'^ERROR\s+service=(?<Service>\S+)\s+code=(?<Code>\d+)\s+message=(?<Message>.+)$' {
[pscustomobject]@{ Level='ERROR'; Service=$Matches.Service; Detail="$($Matches.Code): $($Matches.Message)" }
continue
}
default {
[pscustomobject]@{ Level='OTHER'; Service=$null; Detail=$_ }
}
}
$classified | Format-Table Level, Service, Detail -AutoSize
Each matching branch emits one object and then uses
continue so the same line is not tested against later
clauses. The output remains reusable objects; formatting occurs only
at the end for human display.
Verification checklist
10. Common mistakes to avoid
Assuming first match wins. PowerShell can execute every matching clause unless you change control flow.
Using break when you meant “next item”.
In a collection switch, break stops all remaining
switch processing; continue advances to the next input
value.
Using regex for simple exact keys. Exact or wildcard matching is easier to review when it expresses the rule fully.
Using switch as a static dictionary. If a hashtable can express the relationship as data, prefer the simpler data structure.
11. Knowledge check
Question 1. Does PowerShell
switch stop after the first matching clause by
default?
Question 2. What does continue do
inside a switch that is processing a collection?
Question 3. What does break do
there?
Question 4. When is
-Wildcard preferable to -Regex?
Question 5. When is a hashtable better than switch?
12. Summary
PowerShell switch is a flexible matcher that can
process scalars, collections, and files; use exact, wildcard, regex,
or case-sensitive matching according to the rule. Multiple cases can
match one value, so break and
continue must be intentional. Prefer a lookup hashtable
for simple data mapping, and keep classification output structured
so later pipeline stages can reuse it.
13. Further reading
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.