Welcome PowerShell User! This recipe is just one of the hundreds of useful resources contained in the PowerShell Cookbook.

If you own the book already, login here to get free, online, searchable access to the entire book's content.

If not, the Windows PowerShell Cookbook is available at Amazon, or any of your other favourite book retailers. If you want to see what the PowerShell Cookbook has to offer, enjoy this free 90 page e-book sample: "The Windows PowerShell Interactive Shell".

20.6 Find Files That Match a Pattern

Problem

You want to get a list of files that match a specific pattern.

Solution

Use the Get-ChildItem cmdlet for both simple and advanced wildcard support:

  • To find all items in the current directory that match a PowerShell wildcard, supply that wildcard to the Get-ChildItem cmdlet:

    Get-ChildItem *.txt
  • To find all items in the current directory that match a provider-specific filter, supply that filter to the -Filter parameter:

    Get-ChildItem -Filter *~2*
  • To find all items in the current directory that do not match a PowerShell wildcard, supply that wildcard to the -Exclude parameter:

    Get-ChildItem -Exclude *.txt
  • To find all items in subdirectories that match a PowerShell wildcard, use the -Include and -Recurse parameters, or use the wildcard as part of the -Path parameter:

    Get-ChildItem -Include *.txt -Recurse
    Get-ChildItem *.txt -Recurse
    Get-ChildItem -Path c:\temp\*.txt -Recurse
  • To find all items in subdirectories that match a provider-specific filter, use the -Filter and -Recurse parameters:

    Get-ChildItem -Filter *.txt -Recurse
  • To find all items in subdirectories that do not match a PowerShell wildcard, use the -Exclude and -Recurse parameters:

    Get-ChildItem -Exclude *.txt -Recurse

    Use the Where-Object cmdlet for advanced regular expression support:

  • To find all items with a filename that matches a regular expression, use the Where-Object cmdlet to compare the Name property to the regular expression:

    Get-ChildItem | Where-Object { $_.Name -match '^KB[0-9]+\.log$' }
  • To find all items with a directory name that matches a regular expression, use the Where-Object cmdlet to compare the DirectoryName property to the regular expression:

    Get-ChildItem -Recurse | Where-Object { $_.DirectoryName -match 'Release' }
  • To find all items with a directory name or filename that matches a regular expression, use the Where-Object cmdlet to compare the FullName property to the regular expression:

    Get-ChildItem -Recurse | Where-Object { $_.FullName -match 'temp' }

Discussion

The Get-ChildItem cmdlet supports wildcarding through three parameters:

Path

The -Path parameter is the first (and default) parameter. While you can enter simple paths such as ., C:\, or D:\Documents, you can also supply paths that include wildcards—such as *, *.txt, [a-z]???.log, or even C:\win*\*.N[a-f]?\F*\v2*\csc.exe.

Include/Exclude

The -Include and -Exclude parameters act as a filter on wildcarding that happens on the -Path parameter. If you specify the -Recurse parameter, the -Include and -Exclude wildcards apply to all items returned.

Note

The most common mistake with the -Include parameter comes when you use it against a path with no wildcards. For example, this doesn’t seem to produce the expected results:

Get-ChildItem $env:WINDIR -Include *.log

That command produces no results because you haven’t supplied an item wildcard to the path. Instead, the correct command is:

Get-ChildItem $env:WINDIR\* -Include *.log

Or simply:

Get-ChildItem $env:WINDIR\*.log
Filter

The -Filter parameter lets you filter results based on the provider-specific filtering language of the provider from which you retrieve items. Since PowerShell’s wildcarding support closely mimics filesystem wildcards, and most people use the -Filter parameter only on the filesystem, this seems like a redundant (and equivalent) parameter. A SQL provider, however, would use SQL syntax in its -Filter parameter. Likewise, an Active Directory provider would use LDAP paths in its -Filter parameter.

It may not be obvious, but the filesystem provider’s filtering language isn’t exactly the same as the PowerShell wildcard syntax. For example, the -Filter parameter doesn’t support character ranges:

PS > Get-ChildItem | Select-Object Name

Name
----
A Long File Name With Spaces Also.txt
A Long File Name With Spaces.txt

PS > Get-ChildItem -Filter "[a-z]*"
PS > Get-ChildItem "[a-z]*" | Select-Object Name

Name
----
A Long File Name With Spaces Also.txt
A Long File Name With Spaces.txt
Tip

Provider-specific filtering can often return results far more quickly than the more feature-rich PowerShell wildcards. Because of this, PowerShell internally rewrites your wildcards into a combination of wildcards and provider-specific filtering to give you the best of both worlds!

For more information about PowerShell’s wildcard syntax, type Get-Help about_WildCards.

When you want to perform even more advanced filtering than what PowerShell’s wildcard syntax offers, the Where-Object cmdlet provides infinite possibilities. For example, to exclude certain directories from a search, use the following:

Get-ChildItem -Rec | Where-Object { $_.DirectoryName -notmatch "Debug" }

Or, in a simpler form:

Get-ChildItem -Rec | ? DirectoryName -notmatch Debug

For a filter that’s difficult (or impossible) to specify programmatically, use the Out-GridView cmdlet as demonstrated in Recipe 2.4 to interactively filter the output.

Because of PowerShell’s pipeline model, an advanced file set generated by Get-ChildItem automatically turns into an advanced file set for other cmdlets to operate on:

PS > Get-ChildItem -Rec | Where-Object { $_.Length -gt 20mb } |
     Sort-Object -Descending Length | Select-FilteredObject |
     Remove-Item -WhatIf

What if: Performing operation "Remove File" on Target "C:\temp\backup092.zip".
What if: Performing operation "Remove File" on Target "C:\temp\slime.mov".
What if: Performing operation "Remove File" on Target "C:\temp\hello.mov".

For more information about the Get-ChildItem cmdlet, type Get-Help Get-ChildItem.

For more information about the Where-Object cmdlet, type Get-Help Where-Object.

See Also

Recipe 2.4, “Interactively Filter Lists of Objects”