Delete files by extension older than X days with PowerShell

Decorative title image of PowerShell logo and directory listing

All product names, logos, and brands used in this post are property of their respective owners.

Over the weekend, a colleague of mine approached me and asked about a method to delete log files over a specific age with a specific file extension on Windows Server. This sounded like an excellent task for PowerShell and the Windows Task Scheduler.

A quick Google search yielded many options. The sticking point for this use case was the fact that the log folder contained various logs (different file names and extensions) for various purposes. This is a common situation with Apache Tomcat. Most of the scripts and methods I discovered only took date (older than X days) into account but not the name or extension of the file.

I liked Thomas Maurer’s post on this topic and ended up adapting his script as follows:

REPLACE:

Get-ChildItem $Path | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item

WITH:

Get-ChildItem $Path | Where-Object { $_.Name -like '*.ext' } | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item

This adds a second “filter” (Where-Object), based on the filename. The file extension is part of the Name attribute - in the example above, I used .ext.

The completed script looked like this:

$Path = "C:\temp"
$Daysback = "-60"
$CurrentDate = Get-Date
$DatetoDelete = $CurrentDate.AddDays($Daysback)
Get-ChildItem $Path | Where-Object { $_.Name -like '*.ext' } | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item

Once created, I scheduled in Windows Task Scheduler as follows:

Screenshot of Task Scheduler Action

Program/script: powershell.exe

Add arguments (optional): -ExecutionPolicy Bypass -File C:\scripts\clean-logs.ps1

This worked well for the use case at hand, but would likely not scale for multiple extensions or file names. Note, if you have long paths/file names, and Get-ChildItem throws errors like the following:

Get-ChildItem : Could not find a part of the path ''.
At
+ CategoryInfo: ReadError: (:String) [Get-ChildItem], DirectoryNotFoundException
+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand
Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file
name must be less than 260 characters, and the directory name must be less than 248 characters.
At 
+ CategoryInfo: ReadError: (:String) [Get-ChildItem], PathTooLongException
+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand

You may be able to use the -LiteralPath workaround as follows (depending on your Windows and PowerShell version):

$LiteralPath = "\\?\C:\temp"
$Daysback = "-60"
$CurrentDate = Get-Date
$DatetoDelete = $CurrentDate.AddDays($Daysback)
Get-ChildItem -LiteralPath $LiteralPath | Where-Object { $_.Name -like '*.ext' } | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item

Special thanks to testbob for pointing this out (see Comments).