Auto-Organize Downloads Folder Powershell Script | Windows/macOS/Linux
Your Downloads folder is a graveyard. PDFs from 2023, installer files for software you already installed, and random screenshots you took once and never looked at again.
And every time you open it, you think: “I should clean this up.”
Then you don’t.
I built this script because I was tired (and also lazy) of that cycle. It’s not fancy stuff. It just works.
The Problem Nobody Talks About
Most “cleanup” solutions are too aggressive. They delete stuff you needed. Or they’re too manual, which means you won’t do it. The sweet spot is:
- Auto-sort downloads by type so you can find things
- Stage old files for deletion, don’t nuke them immediately
- Give you a grace period to recover anything you actually need
That’s exactly what this script does.
How It Works (The 90-Day Rule)
Day 0: Download lands in root → Auto-sorted to category folder
Day 60: Still untouched in Documents/Images → Moved to Trash-Temp
Day 90: Still in Trash-Temp → Permanently deleted
Total lifecycle: 90 days. That’s enough time to realize you need something, but not so long that you’re hoarding garbage forever.
The Folder Structure
Downloads/
├── 01-Software/ # .exe, .msi, .dmg, .pkg
├── 02-WordPress/ # Plugin/theme ZIPs (pattern-matched)
├── 03-Documents/ # PDFs, Office docs, CSVs
├── 04-Images/ # Screenshots, photos, videos
├── 05-Archives/ # .zip, .7z, .rar
├── 06-Code-Scripts/ # .py, .js, .json, etc.
└── 99-Trash-Temp/ # Staging area for deletion
Safety First
The script never touches:
- The script file itself
- The log file
- Anything outside your Downloads folder
Files aren’t deleted immediately. They sit in 99-Trash-Temp for 30 days. If you panic, you can recover them. The log tells you exactly what was moved and when.
Setup Instructions
Windows 11 (Native)
- Download the script from [GIST]
- Place it in your Downloads folder (e.g.,
D:\Data\Downloads\2026\) - Edit the path in the script (line ~17) to match your Downloads location:
$BasePath = "C:\Users\YourName\Downloads" - Run once manually to test:
cd D:\Data\Downloads\2026 .\Downloads-Weekly-Cleanup.ps1 -WhatIfThe-WhatIfflag shows what it would do without actually doing it. - Schedule it to run weekly:
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File D:\Data\Downloads\2026\Downloads-Weekly-Cleanup.ps1" $Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At "09:00" $Settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries Register-ScheduledTask -TaskName "Downloads Cleanup" -Action $Action -Trigger $Trigger -Settings $Settings
macOS
PowerShell works on macOS. Install it:
brew install powershell
Then follow the Windows instructions, but change paths:
$BasePath = "/Users/YourName/Downloads"
For scheduling, use launchd instead of Task Scheduler. Create ~/Library/LaunchAgents/com.downloads.cleanup.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.downloads.cleanup</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/pwsh</string>
<string>-File</string>
<string>/Users/YourName/Downloads/Downloads-Weekly-Cleanup.ps1</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Weekday</key>
<integer>1</integer>
<key>Hour</key>
<integer>9</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
Load it:
launchctl load ~/Library/LaunchAgents/com.downloads.cleanup.plist
Linux
Install PowerShell:
# Ubuntu/Debian
sudo apt update
sudo apt install -y powershell
# Or install from Microsoft repo (recommended)
wget -q "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb"
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install -y powershell
Edit the script path:
$BasePath = "/home/YourName/Downloads"
Use cron for scheduling:
# Edit crontab
crontab -e
# Add line for Sunday 9 AM
0 9 * * 0 /usr/bin/pwsh -File /home/YourName/Downloads/Downloads-Weekly-Cleanup.ps1
Configurable Variables
At the top of the script, you can adjust:
param(
[switch]$WhatIf, # Dry run mode
[int]$TrashDays = 30, # Days before trash is deleted (default: 30)
[int]$AgingDays = 60 # Days before aging to trash (default: 60)
)
More aggressive cleanup:
.\Downloads-Weekly-Cleanup.ps1 -AgingDays 30 -TrashDays 14
More lenient:
.\Downloads-Weekly-Cleanup.ps1 -AgingDays 90 -TrashDays 60
Customizing File Patterns
The script has two places you can customize:
1. Extension-to-Folder Mapping (~line 30)
$Folders = @{
'01-Software' = @('.exe', '.msi', '.msix', '.dmg', '.pkg')
'03-Documents' = @('.pdf', '.docx', '.csv', '.txt')
'04-Images' = @('.jpg', '.png', '.mp4', '.mov')
# ... add your own
}
2. WordPress Patterns (~line 44)
If you work with WordPress, add plugin patterns:
$WordPressPatterns = @(
'*placescale*.zip',
'*woocommerce*.zip',
'*your-plugin*.zip'
)
What the Log Looks Like
[2026-03-26 17:36:15] [INFO] Organization complete: 0 moved, 0 skipped, 0 errors
[2026-03-26 17:36:15] [WARN] Aged file moved: [03-Documents] old-invoice.pdf (79d old)
[2026-03-26 17:36:15] [WARN] Deleted: jetbrains-fonts.zip (12.49 MB) - Last modified: 01/25/2026
Everything is timestamped. If you need to recover something, you’ll know exactly when it was moved or deleted.
Why Not Just Use Any Existing Tool?
- CCleaner/BleachBit: Too aggressive. No staging. You find out too late.
- macOS Automator: Works, but fragile. Breaks silently.
- Manual cleanup: You won’t do it. Would you?
This script gives you structure and safety. The 90-day lifecycle means you’re not hoarding, but you’re also not panicking.
Download
Fork it. Modify it. Make it yours. The code is straightforward PowerShell—no dependencies, no external calls, no surprises.
I use this every week. It works.