How-to: PowerShell Wildcards

The four types of Wildcard:

The * wildcard will match zero or more characters

The ? wildcard will match a single character

[m-n] Match a range of characters from m to n, so [f-m]ake will match fake/jake/make

[abc] Match a set of characters a,b,c.., so [fm]ake will match fake/make

Unlike the rather fuzzy logic of MS-DOS and the CMD shell, PowerShell wildcards are consistent in their meaning so *.* will match any characters followed by a period (.) followed by any characters. In other words *.* will return only items that have an extension, and so most directories will not be matched.

To return all items just use a single *

When recursing a file hierarchy, it is necessary to use the wildcard as part of an -include clause:
Get-ChildItem c:\windows -include *.exe -recurse

Using a wildcard character without -include:
Get-ChildItem c:\windows\*.exe -recurse
the above will not match a file such as C:\windows\test\demo.exe

When using WMI filters use the WMI specific wildcards: % for zero or more characters, _ for a single character.

Wildcards will also work within both single and double quotes, to prevent wildcard expansion use the -LiteralPath parameter where available.

-Like for string comparison

To perform a comparison of strings, use the -Like or -notlike operators, these comparison operators support the 4 wildcards above.

PS C:\> 'hunting the snark' -like '*snark*'

For more complex expressions, use the -match operator with a regular expression.

The –Filter parameter

The Get-ChildItem -filter parameter specifies a filter in the provider’s format or language.
In the case of an SQL provider, the -Filter parameter might offer SQL syntax ( -Filter “WHERE Name LIKE %pattern%”)
In the case of the Filesystem provider the pattern is processed by Win32 API (FindFirstFile).

This means that -filter has the same file resolution and almost the same wildcarding as CMD.exe, which utilises the same Win32 API. The difference in wildcarding is that the FileSystem provider supports the [] bracket pattern syntax, and CMD.exe does not.

CMD/Win32 wildcards are not very intuitive largely for historical reasons, they match against both short (8.3) and long filenames

For example:

In a wildcard pattern ending with .* the .* is ignored.
So *.* is the same as * and demo*.* is the same as demo* this means it will match 'demonstrate' a filename with no .extension.

The ? wildcard will not match a dot, so while you might expect demo???? to match 'demo.txt' it will not, you need to use demo.???

When matching extensions there is an implied wilcard at the end because short filenames are limited to a 3 character extension, so for example *.HTM will match the file 'demo.HTML', but *.HT will not.

The 'Old New Thing' blog has more detail on how and why MS-DOS wildcards work this way.

In PowerShell v1 there was a significant performance benefit to using -filter over a native PowerShell wildcard, but in v2 Microsoft added support for partial filtering to the Filesystem provider. This offloads as much of the filtering work as it can to the raw Win32 APIs – and then does more powerful (and correct) wildcard matching on the smaller set of results.

This means that when it comes to the Filesystem provider, you probably don’t want or need the -Filter parameter []


PS C:\> Get-ChildItem c:\work\*.xlsx

PS C:\> Get-ChildItem c:\work\[a-f]*.txt

PS C:\> Get-ChildItem -literalpath 'c:\work\test[1].txt'

PS C:\> Get-ChildItem -recurse -filter c:\work\demo.*

“We usually see only the things we are looking for, so much that we sometimes see them where they are not” ~ Eric Hoffer

Related PowerShell Cmdlets

Regular Expressions - Search for a string.
Get-ChildItem - Get child items (contents of a folder or registry key)
Comparison operators -like, -lt, -gt, -eq, -ne, -match

Copyright © 1999-2024
Some rights reserved