Decide between a watcher and a schedule
A file system watcher reacts instantly but misses files that existed before it started, and it fires while a download is still being written. A scheduled run every ten minutes is duller and far more reliable.
A Downloads folder that sorts itself by extension saves a minute every day. A scheduled script with a dry-run mode and a log does it without the risk of losing files.
Map **extensions to folders**, move files with a **scheduled PowerShell script**, and skip anything modified in the last **two minutes** so a download in progress is never moved. Log every move.
A file system watcher reacts instantly but misses files that existed before it started, and it fires while a download is still being written. A scheduled run every ten minutes is duller and far more reliable.
The script should only move files into folders that already exist, so a typo cannot create a dozen stray directories. Make one folder per type and keep the names short.
New-Item -ItemType Directory -Path D:\orted\ocs, D:\orted\mages, D:\orted\nstallers
Read the folder, filter by extension and print what would happen before anything moves. The -WhatIf switch is built into the move command and costs nothing to use.
Get-ChildItem $env:USERPROFILE\ownloads -File | Where-Object { $_.Extension -in '.pdf','.docx' } | Move-Item -Destination D:\orted\ocs -WhatIf
A download writes into the target folder for seconds or minutes. Filter on the last write time so the run only touches files that have been quiet for a while.
$cutoff = (Get-Date).AddMinutes(-2)
... | Where-Object { $_.LastWriteTime -lt $cutoff }
Create a task that runs as your account every ten minutes with the highest privileges off. Running as the logged-on user keeps the network drive mappings and the profile paths intact.
schtasks /create /tn "Sort Downloads" /tr "powershell -NoProfile -ExecutionPolicy Bypass -File C:\ools\ort-downloads.ps1" /sc minute /mo 10
One line per file with a timestamp turns a mysterious disappearance into a five second lookup. Write to a file next to the script, not to the console, which nobody sees in a scheduled run.
Add-Content C:\ools\ort.log "$(Get-Date -f s) $($_.Name) -> Docs"
The working directory in a scheduled task is not your home folder. Use absolute paths everywhere or set the start-in folder in the task.
Execution policy. Either pass -ExecutionPolicy Bypass in the task action or set it for the current user once.
Check the log first, then the extension list. A catch-all default rule is what usually surprises people.
The folder is synced and the app protects it. Exclude Downloads from the sync or move the whole folder out of OneDrive.
Yes. Group on LastWriteTime and build the folder name from the month; the loop stays the same.
Yes. Both the script and the scheduled task behave the same on 10 and 11.
Run **Unregister-ScheduledTask -TaskName "Sort Downloads" -Confirm:$false** and the automation stops. Files already moved stay in the destination folders; move them back by hand or with one Get-ChildItem loop.
Free · no account needed · tracks your progress