PowerShell Genie

PowerShell Regex and wildcards

PowerShell has two separate pattern systems and mixing them up wastes a lot of time.

Lesson 3 min read Windows PowerShell 5.1 and PowerShell 7

Documentation: Microsoft Learn

Overview

Wildcards are simple: * matches any number of characters, ? matches exactly one. They are what -like uses, and what the -Filter and -Path parameters of file commands accept. Wildcards are all you need for most filename work.

Regular expressions are the full pattern language, used by -match, -replace and -split, and by Select-String. In a regex, . means any character, \d means a digit, + means one or more, and ^ and $ anchor to the start and end of the string. A dot in a regex is not a literal dot, which is the single most common source of confusion when moving from wildcards.

When -match succeeds it populates $Matches, a hashtable holding the whole match at key 0 and any capture groups after it. Named groups, written (?<name>...), land in $Matches.name and are far easier to read than counting parentheses.

For filtering files, prefer -Filter over piping to Where-Object. -Filter is handled by the filesystem provider before objects are created, so it is dramatically faster on large directories.

What happens

The first line uses wildcards. -Filter '*.ps1' asks the filesystem for names ending in .ps1, and the provider applies it while enumerating, so PowerShell never builds objects for the files you did not want. On a directory with 200,000 files that is the difference between seconds and minutes.

The second line uses regex. -match returns True and fills $Matches, and the escaped \.log at the end is a literal dot rather than the any-character dot. The named group (?<date>...) means the captured value is $Matches.date instead of $Matches[1], which is what the last line reads. Two patterns, two systems, on purpose.

Worth remembering

  • Wildcards (* and ?) are for -like and file paths.
  • Regex is for -match, -replace, -split and Select-String.
  • In regex, . means any character. Escape it as \. for a literal dot.
  • -match fills $Matches, including named capture groups.
  • $Matches is only refreshed when -match succeeds — after a failed match it still holds the previous match's values. Always test the $true/$false result before reading $Matches.

Primary documentation

Get-ChildItem reference · Select-Object reference

Try it

Browser simulation · fictional data; no changes to your computer.

Interactive simulation · fictional data

Filters files with a wildcard, then parses a filename with a named regex group.

Show reference output

Browser dataset output · the real environment will differ

Name        Length  
----------  --------
app.log     12582912
errors.log  26214400
trace.log   524288  

Keep going

Next: PowerShell Services
Genie guidePowerShell Regex and wildcards

PowerShell has two separate pattern systems and mixing them up wastes a lot of time.