PowerShell Find Files by Name or Extension Recursively

PowerShell Find Files by Name or Extension Recursively

PowerShell Tips Editor 2 min read
PowerShell Find Files by Name or Extension Recursively

You know the file is somewhere on the server. It’s a .bak file, or maybe you remember part of the name. File Explorer will grind through directories for minutes — PowerShell finds it in seconds and returns a real object you can act on. This guide covers every approach to PowerShell find files recursively: by extension, partial name, date, size, and across multiple drives, with examples you can use immediately.

Find All Files by Extension

The fastest approach for extension-based search uses -Filter, which filters at the OS level:

# Find all .log files recursively
Get-ChildItem -Path 'C:\' -Filter '*.log' -Recurse -ErrorAction SilentlyContinue

# Find all PowerShell scripts
Get-ChildItem -Path 'C:\Scripts' -Filter '*.ps1' -Recurse

# Get just the full paths
Get-ChildItem -Path 'C:\' -Filter '*.bak' -Recurse -File -ErrorAction SilentlyContinue |
    Select-Object FullName, Length, LastWriteTime
FullName                                    Length    LastWriteTime
--------                                    ------    -------------
C:\Databases\prod\backup.bak         5368709120    4/30/2026 2:00 AM
C:\Databases\dev\dev-backup.bak       536870912    5/1/2026 11:00 PM

Always add -ErrorAction SilentlyContinue when searching from a drive root — access-denied errors on system folders will stop the search without it.

Find by Partial Name with Wildcards

When you know part of the filename, use wildcards in -Filter or -Name:

# Find files with 'deploy' anywhere in the name
Get-ChildItem -Path 'C:\Projects' -Filter '*deploy*' -Recurse

# Find files starting with a date pattern
Get-ChildItem -Path 'C:\Logs' -Filter '2026-05-*' -Recurse

# Case-insensitive wildcard — -Filter is already case-insensitive
Get-ChildItem 'C:\' -Filter '*backup*' -Recurse -File -ErrorAction SilentlyContinue |
    Select-Object -First 20 FullName
FullName
--------
C:\Backups\system-backup-2026-05-01.zip
C:\SQL\backup\full-backup.bak
C:\Scripts\run-backup.ps1

Search in Multiple Drives

Search across all drives by iterating the drive list:

# Search all local drives
$localDrives = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Used -ne $null }

foreach ($drive in $localDrives) {
    Write-Output "Searching $($drive.Name):..."
    Get-ChildItem "$($drive.Name):\" -Filter '*.mdf' -Recurse -File -ErrorAction SilentlyContinue |
        Select-Object FullName, @{ Name='SizeGB'; Expression={ [math]::Round($_.Length/1GB,2) } }
}

# One-liner version
Get-PSDrive -PSProvider FileSystem |
    ForEach-Object { Get-ChildItem "$($_.Name):\" -Filter '*.iso' -Recurse -File -ErrorAction SilentlyContinue }
Searching C:...
Searching D:...

FullName                          SizeGB
--------                          ------
C:\SQL\Data\Production.mdf          4.82
D:\Databases\Archive\Old.mdf        1.23

Filter by Date Modified

Find files modified within a specific time window:

# Files modified in the last 24 hours
$since = (Get-Date).AddHours(-24)
Get-ChildItem 'C:\Logs' -Recurse -File |
    Where-Object { $_.LastWriteTime -gt $since } |
    Select-Object FullName, LastWriteTime

# Files older than 90 days (cleanup candidates)
$cutoff = (Get-Date).AddDays(-90)
Get-ChildItem 'C:\Logs\Archive' -Recurse -File |
    Where-Object { $_.LastWriteTime -lt $cutoff } |
    Select-Object FullName, LastWriteTime, Length

# Files created today
$today = (Get-Date).Date
Get-ChildItem 'C:\Downloads' -File |
    Where-Object { $_.CreationTime -ge $today }
FullName                         LastWriteTime
--------                         -------------
C:\Logs\app.log                  5/4/2026 9:15 AM
C:\Logs\error.log                5/4/2026 8:01 AM

Find Largest Files

The classic disk space investigation — find the biggest files consuming space:

# Top 20 largest files on C: drive
Get-ChildItem -Path 'C:\' -Recurse -File -ErrorAction SilentlyContinue |
    Sort-Object Length -Descending |
    Select-Object -First 20 FullName,
        @{ Name='SizeGB'; Expression={ [math]::Round($_.Length/1GB,3) } } |
    Format-Table -AutoSize

# Files larger than 1GB specifically
Get-ChildItem -Path 'C:\' -Recurse -File -ErrorAction SilentlyContinue |
    Where-Object { $_.Length -gt 1GB } |
    Select-Object FullName, @{ Name='SizeGB'; Expression={ [math]::Round($_.Length/1GB,2) } } |
    Sort-Object SizeGB -Descending
FullName                                    SizeGB
--------                                    ------
C:\Windows\Installer\archive.msi             5.120
C:\Users\Alice\Videos\vacation.mp4           3.847
C:\Databases\prod\Production.mdf             4.820

Export Search Results

Get-ChildItem -Path 'C:\' -Filter '*.log' -Recurse -File -ErrorAction SilentlyContinue |
    Select-Object FullName, Name, Length, LastWriteTime,
        @{ Name='SizeMB'; Expression={ [math]::Round($_.Length/1MB,2) } } |
    Sort-Object Length -Descending |
    Export-Csv 'C:\Reports\log-file-inventory.csv' -NoTypeInformation

Write-Output "Inventory saved to C:\Reports\log-file-inventory.csv"

Common Errors and Fixes

  • -Filter only accepts one pattern; use -Include for multiple: Get-ChildItem -Filter '*.log','*.txt' silently uses only the first pattern. For multiple extensions, use -Include @('*.log','*.txt') -Recurse, or pipe to Where-Object { $_.Extension -in @('.log','.txt') }.
  • Access denied on system folders stops recursion: Without -ErrorAction SilentlyContinue, the first inaccessible folder terminates the entire search. Always include this flag for any recursive search starting at a drive root or system path.

Related Cmdlets / See Also

Wrapping Up

PowerShell file finding is faster and more capable than File Explorer. Use -Filter for single-extension searches, -Include for multiple extensions, and Where-Object for date and size filters. Always add -ErrorAction SilentlyContinue when recursing from drive roots. Export results to CSV for documentation. Your next step: find all files larger than 500MB on your server’s data drive and export the list for cleanup review.

Send-Item -To