Recently, I was working on a server cleanup project where I needed to delete thousands of log files that were older than 90 days. These files were taking up valuable disk space, and manually identifying and deleting them would have been incredibly time-consuming.
In this tutorial, I’ll show you how to create PowerShell scripts that can identify and delete files older than a specified number of days with particular extensions.
Let’s explore different approaches to delete files older than X days with specific extensions in PowerShell.
Method 1: Basic PowerShell Script to Delete Old Files
The simplest approach uses PowerShell’s Get-ChildItem cmdlet combined with Where-Object to filter files by date and extension, then Remove-Item to delete them.
Here’s a basic script that will delete log files older than 30 days:
# Set parameters
$Path = "C:\Logs"
$DaysBack = 30
$Extension = "*.log"
# Calculate the date threshold
$CurrentDate = Get-Date
$DateThreshold = $CurrentDate.AddDays(-$DaysBack)
# Get files older than the threshold and delete them
Get-ChildItem -Path $Path -Filter $Extension -Recurse |
Where-Object { $_.LastWriteTime -lt $DateThreshold } |
Remove-Item -Force
Let me break down how this script works:
- We define three parameters: the folder path, how many days back to check, and the file extension.
- We calculate the date threshold by taking the current date and subtracting the specified number of days.
- We use
Get-ChildItemto find all files with the specified extension. - The
Where-Objectcmdlet filters the list to include only files older than our threshold date. - Finally,
Remove-Itemdeletes the filtered files.
When I used this script on my development server, it successfully cleared over 2GB of old log files in seconds!
Check out How to Count Files in a Folder Using PowerShell
Method 2: Create a Reusable Function
Let me make it easy for you. I will show you how to create a reusable function using PowerShell. You can call this function with different parameters.
Here is the complete PowerShell script:
function Remove-OldFiles {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$FolderPath,
[Parameter(Mandatory=$true)]
[int]$DaysOld,
[Parameter(Mandatory=$true)]
[string]$Extension,
[switch]$WhatIf
)
$CurrentDate = Get-Date
$DateThreshold = $CurrentDate.AddDays(-$DaysOld)
Write-Host "Searching for *$Extension files older than $DaysOld days in $FolderPath..."
$FilesToDelete = Get-ChildItem -Path $FolderPath -Filter "*$Extension" -Recurse |
Where-Object { $_.LastWriteTime -lt $DateThreshold }
$TotalSize = ($FilesToDelete | Measure-Object -Property Length -Sum).Sum / 1MB
Write-Host "Found $($FilesToDelete.Count) files to delete (approximately $([math]::Round($TotalSize, 2)) MB)"
if ($WhatIf) {
$FilesToDelete | ForEach-Object {
Write-Host "Would delete: $($_.FullName) - Last modified: $($_.LastWriteTime)"
}
}
else {
$FilesToDelete | Remove-Item -Force
Write-Host "Deleted $($FilesToDelete.Count) files"
}
}
This function adds several improvements:
- Parameter validation to ensure you provide all required information
- A
-WhatIfparameter that lets you preview what would be deleted without actually deleting anything - Detailed reporting that shows how many files will be deleted and their total size
- Better error handling through the
[CmdletBinding()]attribute
You can call this function in different ways:
# Delete log files older than 60 days
Remove-OldFiles -FolderPath "D:\ServerBackups" -DaysOld 60 -Extension ".log"
# Preview deletion of old CSV files without actually deleting them
Remove-OldFiles -FolderPath "C:\Reports" -DaysOld 90 -Extension ".csv" -WhatIf
Check out PowerShell Write to File UTF-8
Method 3: Handle Multiple Extensions at Once
Sometimes you need to delete files with different extensions. Here’s how to handle multiple extensions in a single PowerShell script:
# Set parameters
$Path = "C:\UserData\TempFiles"
$DaysBack = 45
$Extensions = @(".tmp", ".log", ".bak")
# Calculate the date threshold
$CurrentDate = Get-Date
$DateThreshold = $CurrentDate.AddDays(-$DaysBack)
# Process each extension
foreach ($Extension in $Extensions) {
Write-Host "Processing files with extension: $Extension"
$FilesToDelete = Get-ChildItem -Path $Path -Filter "*$Extension" -Recurse |
Where-Object { $_.LastWriteTime -lt $DateThreshold }
$Count = $FilesToDelete.Count
if ($Count -gt 0) {
$FilesToDelete | Remove-Item -Force
Write-Host "Deleted $Count files with extension $Extension" -ForegroundColor Green
}
else {
Write-Host "No files found with extension $Extension to delete" -ForegroundColor Yellow
}
}
I’ve used this approach to clean up our company’s image processing server, where we needed to remove temporary files with various extensions (.tmp, .bak, .old) that accumulated during processing.
Check out PowerShell Test-Path
Method 4: Schedule with Task Scheduler
You can schedule your PowerShell script to run periodically using Windows Task Scheduler for automated maintenance.
First, save your script as a .ps1 file, for example, CleanupOldFiles.ps1.
Then, create a scheduled task:
- Open Task Scheduler (taskschd.msc)
- Create a new Basic Task
- Set a name like “Weekly File Cleanup”
- Choose your trigger (e.g., Weekly on Sunday at 2:00 AM)
- For the action, select “Start a program”
- In the Program/script field, enter:
powershell.exe - In the Add arguments field, enter:
-ExecutionPolicy Bypass -File "C:\Scripts\CleanupOldFiles.ps1"
This ensures your cleanup runs automatically at the scheduled time, keeping your system tidy without manual intervention.
Check out Write to File Line by Line in PowerShell
Method 5: Logging Deletion Activity
For audit purposes, I recommend adding logging capabilities to your script:
# Set parameters
$Path = "C:\ApplicationLogs"
$DaysBack = 30
$Extension = "*.txt"
$LogFile = "C:\Scripts\Logs\DeletionLog.txt"
# Ensure log directory exists
$LogDir = Split-Path $LogFile -Parent
if (!(Test-Path $LogDir)) {
New-Item -ItemType Directory -Path $LogDir -Force
}
# Start logging
$TimeStamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"[$TimeStamp] Starting cleanup process for *$Extension files older than $DaysBack days" | Out-File $LogFile -Append
# Calculate the date threshold
$CurrentDate = Get-Date
$DateThreshold = $CurrentDate.AddDays(-$DaysBack)
# Get files and delete them, logging each one
$Files = Get-ChildItem -Path $Path -Filter $Extension -Recurse |
Where-Object { $_.LastWriteTime -lt $DateThreshold }
foreach ($File in $Files) {
try {
Remove-Item $File.FullName -Force
"[$TimeStamp] Deleted: $($File.FullName) (Last modified: $($File.LastWriteTime))" | Out-File $LogFile -Append
}
catch {
"[$TimeStamp] ERROR deleting $($File.FullName): $($_.Exception.Message)" | Out-File $LogFile -Append
}
}
# Log summary
"[$TimeStamp] Cleanup complete. Deleted $($Files.Count) files." | Out-File $LogFile -Append
This script creates a detailed log of all deleted files, including timestamps and any errors that might occur. These logs have saved me countless hours when investigating why certain files were removed or when troubleshooting script issues.
Read Write to File without Carriage Return in PowerShell
Method 6: Delete Specific Files Based on CreationTime
Sometimes, LastWriteTime isn’t the right property to use. For instance, when cleaning up backup files, you might want to use CreationTime instead:
# Set parameters
$Path = "E:\DatabaseBackups"
$DaysBack = 180 # Keep backups for 6 months
$Extension = "*.bak"
# Calculate the date threshold
$CurrentDate = Get-Date
$DateThreshold = $CurrentDate.AddDays(-$DaysBack)
# Get files older than the threshold based on creation time and delete them
Get-ChildItem -Path $Path -Filter $Extension -Recurse |
Where-Object { $_.CreationTime -lt $DateThreshold } |
Remove-Item -Force
This approach ensures that you delete files based on their creation date rather than their last modification date.
Best Practices and Considerations
Now, let me show you a few best practices for deleting files older than X Days with Specific Extensions using PowerShell.
- Always test with -WhatIf first: Before running a deletion script on production data, use the
-WhatIfparameter to preview what will be deleted. - Start with a narrow scope: Begin with a specific folder and extension rather than targeting your entire system.
- Consider file importance: Some files, despite their age, might be critical. Add exclusion logic for important files.
- Mind the recursion: Be careful when using
-Recursein folders with many subfolders, as the script might take longer to run. - Add error handling: Proper try/catch blocks ensure your script continues running even if it encounters permission issues or locked files.
Check out Append Text to Files in PowerShell
PowerShell Script to Delete Files Older Than 30 Days
Here is a particular example, here, I will explain how to delete files older than 30 days using PowerShell. I’ll show you how to create a PowerShell script that can identify and delete files older than 30 days.
The best approach uses PowerShell’s Get-ChildItem cmdlet combined with Where-Object to filter files by date, then Remove-Item to delete them.
Here’s a basic PowerShell script that will delete files older than 30 days:
# Set parameters
$Path = "C:\Logs"
$DaysBack = 30
# Calculate the date threshold
$CurrentDate = Get-Date
$DateThreshold = $CurrentDate.AddDays(-$DaysBack)
# Get files older than the threshold and delete them
Get-ChildItem -Path $Path -Recurse -File |
Where-Object { $_.LastWriteTime -lt $DateThreshold } |
Remove-Item -Force
Let me break down how this script works:
- We define two parameters: the folder path and how many days back to check (30 days in this case).
- We calculate the date threshold by taking the current date and subtracting 30 days.
- We use
Get-ChildItemto find all files in the specified path, including subfolders. - The
Where-Objectcmdlet filters the list to include only files older than our threshold date. - Finally,
Remove-Itemdeletes the filtered files.
When I used this script on my development server, it successfully cleared over 2GB of old files in seconds!
Before you run the script to actually delete files, it’s always a good practice to first see what files would be deleted. You can do this by simply listing the files instead of deleting them:
# Set parameters
$Path = "C:\Logs"
$DaysBack = 30
# Calculate the date threshold
$CurrentDate = Get-Date
$DateThreshold = $CurrentDate.AddDays(-$DaysBack)
# List files older than the threshold
Get-ChildItem -Path $Path -Recurse -File |
Where-Object { $_.LastWriteTime -lt $DateThreshold } |
Select-Object FullName, LastWriteTime
This will display a list of the files that would be deleted, along with their last write times, without actually deleting anything.
Conclusion
I hope now you learn how to delete files older than X days with specific extensions using PowerShell. I hope you found this tutorial helpful! If you have any questions or suggestions, feel free to leave them in the comments below.
You may also like the following tutorials:
- Rename Multiple Files Using PowerShell
- Check if a File Exists and Rename it Using PowerShell
- Download a File from URL Using PowerShell
- Check If File Modified In Last 24 Hours Using PowerShell

Hey! I’m Bijay Kumar, founder of SPGuides.com and a Microsoft Business Applications MVP (Power Automate, Power Apps). I launched this site in 2020 because I truly enjoy working with SharePoint, Power Platform, and SharePoint Framework (SPFx), and wanted to share that passion through step-by-step tutorials, guides, and training videos. My mission is to help you learn these technologies so you can utilize SharePoint, enhance productivity, and potentially build business solutions along the way.