Skip to content

Instantly share code, notes, and snippets.

@wincmd64
Last active November 16, 2024 11:59
Show Gist options
  • Save wincmd64/54cf6764bf4d00513138922b47767a08 to your computer and use it in GitHub Desktop.
Save wincmd64/54cf6764bf4d00513138922b47767a08 to your computer and use it in GitHub Desktop.
# Recursively deletes files to the Recycle Bin older than X days in specified folder
#
# Example usage: powershell clean.ps1 -d 7 -dir $env:TEMP -ext ".tmp .log"
#
# Parameters:
# -d X : Specifies that files older than X days will be deleted (mandatory)
# -dir "path" : Specifies the directory to search for files; defaults to the current directory if not provided
# -ext ".ext1 .ext2 ..." : Specifies the file extensions to delete (optional)
# -test : If specified, shows files that would be deleted without actually deleting them
param (
[int]$d,
[string]$dir = (Get-Location),
[string]$ext,
[switch]$test
)
# Check for mandatory parameter
if (-not $d -or $d -le 0) {
Write-Host "Error: Please use -d to specify a positive number of days."
exit 1
}
# Checking the existence of a directory
if (-not (Test-Path -Path $dir)) {
Write-Host "Error: The directory '$dir' does not exist."
exit 1
}
# Determine the script name
$scriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name)
$logFile = "$env:TEMP\$scriptName`_$(Get-Date -Format 'yy-MM-dd-HH-mm-ss').log"
$count = 0
$errorCount = 0
# Create an array of extensions if provided
$extensions = if ($ext) { $ext -split ' ' } else { @() }
# Get files to delete based on the specified extensions
$filesToDelete = Get-ChildItem -EA SilentlyContinue -Path $dir -File -Recurse |
Where-Object {
$_.LastWriteTime -lt (Get-Date).AddDays(-$d) -and
($extensions.Count -eq 0 -or $extensions -contains $_.Extension)
}
if ($filesToDelete.Count -eq 0) {
Write-Host "No files found to delete."
} else {
if ($test) {
$extensionCounts = @{}
foreach ($file in $filesToDelete) {
$ext = $file.Extension
if ($extensionCounts.ContainsKey($ext)) {
$extensionCounts[$ext]++
} else {
$extensionCounts[$ext] = 1
}
}
Write-Host "TEST MODE. Will try to delete $($filesToDelete.Count) files:"
foreach ($ext in $extensionCounts.Keys) {
Write-Host "$ext - $($extensionCounts[$ext])"
}
} else {
Add-Type -AssemblyName Microsoft.VisualBasic
# Initialize progress bar
$progressParams = @{
Activity = "Deleting files"
CurrentOperation = "Finding files to delete..."
PercentComplete = 0
}
Write-Progress @progressParams
$totalFiles = $filesToDelete.Count
foreach ($file in $filesToDelete) {
try {
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($file.FullName, [Microsoft.VisualBasic.FileIO.UIOption]::OnlyErrorDialogs, [Microsoft.VisualBasic.FileIO.RecycleOption]::SendToRecycleBin)
$count++
# Update progress bar
$progressParams.PercentComplete = [math]::Round(($count / $totalFiles) * 100)
$progressParams.CurrentOperation = "Deleting: $($file.FullName)"
Write-Progress @progressParams
} catch {
Add-Content -Path $logFile -Value "Error deleting $($file.FullName): $_"
$errorCount++
}
}
# Complete progress bar
$progressParams.PercentComplete = 100
$progressParams.CurrentOperation = "Completed"
Write-Progress @progressParams
# Summary
Write-Host "Deleted files: $count"
Write-Host "Files with errors: $errorCount"
if ($errorCount -gt 0) {
Write-Host "Log file created: $logFile"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment