一键整理下载:用 PowerShell + 任务计划把下载文件夹自动分类归档

2026年01月21日/ 浏览 8

很多人下载文件后习惯放在“下载”文件夹,久而久之混乱难找。本文教你用一个可复用的 PowerShell 脚本,每天自动把 Downloads 中的文件按 文件类型(如 图片/文档/压缩/视频/音频/可执行)和创建日期归档到对应的子文件夹,并做去重与日志记录。零第三方,10 分钟上手。

为什么这样做(30 秒)

自动分类,节省找文件时间;支持按天或按月归档(按需切换);支持“演练模式”(dry-run)先预览改动,防止误操作;可用任务计划自动化、长期运行。

准备(1 分钟)

Windows 11(或 Windows 10)带 PowerShell 即可。用户目录的 Downloads(或任意你希望整理的目录)。管理员权限非必须(除非你要整理系统目录)。

把脚本放好(可直接复制粘贴)

在 C:\Scripts\ 下新建文件 AutoSortDownloads.ps1,把下面内容完整粘贴并保存:

<#

AutoSortDownloads.ps1

功能:按类型 + 日期(按日或按月)把下载目录中的文件移动到分类子目录

使用:PowerShell -ExecutionPolicy Bypass -File "C:\Scripts\AutoSortDownloads.ps1" [-Source "C:\Users\you\Downloads"] [-Mode "dryrun"|"apply"] [-DateMode "Daily"|"Monthly"]

说明:默认 source 为当前用户 Downloads,默认 Mode 为 dryrun(仅预览),默认 DateMode 为 Monthly

#>

param(

[string]$Source = "$env:USERPROFILE\Downloads",

[ValidateSet("dryrun","apply")]

[string]$Mode = "dryrun",

[ValidateSet("Daily","Monthly")]

[string]$DateMode = "Monthly",

[string[]]$Exclude = @("*.crdownload","*.tmp") # 排除规则(支持通配符)

)

# 配置区:按需修改

$Mapping = @{

"Images" = @("*.jpg","*.jpeg","*.png","*.gif","*.bmp","*.webp","*.heic")

"Documents" = @("*.pdf","*.doc","*.docx","*.xls","*.xlsx","*.ppt","*.pptx","*.txt","*.md")

"Archives" = @("*.zip","*.rar","*.7z","*.tar","*.gz","*.iso")

"Videos" = @("*.mp4","*.mkv","*.mov","*.avi","*.flv")

"Audio" = @("*.mp3","*.wav","*.flac","*.m4a")

"Executables"= @("*.exe","*.msi","*.bat","*.ps1")

"Others" = @("*") # 默认 catch-all

}

$LogDir = Join-Path $Source "AutoSortLogs"

if (-not (Test-Path $LogDir)) { New-Item -Path $LogDir -ItemType Directory | Out-Null }

$LogFile = Join-Path $LogDir ("AutoSort_{0}.log" -f (Get-Date -Format "yyyyMMdd"))

function Write-Log {

param($text)

$time = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")

"$time`t$text" | Out-File -FilePath $LogFile -Encoding UTF8 -Append

}

function Should-Exclude {

param($name)

foreach ($pattern in $Exclude) {

if ($name -like $pattern) { return $true }

}

return $false

}

# 生成目标子目录名(按分类 + 日期)

function Get-TargetFolder {

param($baseFolder, $category, [datetime]$dt)

if ($DateMode -eq "Daily") {

$datePart = $dt.ToString("yyyy-MM-dd")

} else {

$datePart = $dt.ToString("yyyy-MM")

}

return Join-Path $baseFolder (Join-Path $category $datePart)

}

# 主流程

Write-Log "=== AutoSort start. Mode=$Mode; Source=$Source; DateMode=$DateMode ==="

if (-not (Test-Path $Source)) {

Write-Log "Source path not found: $Source. Exit."

throw "Source path not found: $Source"

}

# 枚举文件(不递归到子目录,仅整理 Source 根目录中的文件;如需递归改 -Recurse)

$files = Get-ChildItem -Path $Source -File -Force

foreach ($f in $files) {

$name = $f.Name

if (Should-Exclude $name) {

Write-Log "Skip excluded: $name"

continue

}

# 找到分类

$matchedCategory = $null

foreach ($cat in $Mapping.Keys) {

foreach ($pat in $Mapping[$cat]) {

if ($name -like $pat) {

$matchedCategory = $cat

break

}

}

if ($matchedCategory) { break }

}

if (-not $matchedCategory) { $matchedCategory = "Others" }

$targetFolder = Get-TargetFolder -baseFolder $Source -category $matchedCategory -dt $f.CreationTime

if (-not (Test-Path $targetFolder)) {

if ($Mode -eq "apply") { New-Item -Path $targetFolder -ItemType Directory -Force | Out-Null }

Write-Log "Create folder: $targetFolder"

}

# 目标文件路径

$targetPath = Join-Path $targetFolder $name

# 若目标已存在,重命名原文件(添加时间戳)

if (Test-Path $targetPath) {

$ts = (Get-Date).ToString("yyyyMMdd_HHmmss")

$base = [System.IO.Path]::GetFileNameWithoutExtension($name)

$ext = [System.IO.Path]::GetExtension($name)

$newName = "$base`_$ts$ext"

$targetPath = Join-Path $targetFolder $newName

Write-Log "Target exists. Renaming to: $newName"

}

if ($Mode -eq "dryrun") {

Write-Log "DRYRUN: Move $($f.FullName) -> $targetPath"

} else {

try {

Move-Item -Path $f.FullName -Destination $targetPath -Force

Write-Log "Moved: $($f.FullName) -> $targetPath"

} catch {

Write-Log "ERROR moving $($f.FullName): $_"

}

}

}

Write-Log "=== AutoSort finished ===`n"

如何使用(3 种常见场景)

1) 先预览(强烈推荐)

在 PowerShell(普通用户)中运行(脚本默认为 dryrun):

PowerShell -ExecutionPolicy Bypass -File "C:\Scripts\AutoSortDownloads.ps1" -Source "$env:USERPROFILE\Downloads" -Mode dryrun -DateMode Monthly

查看 Downloads\AutoSortLogs\AutoSort_yyyyMMdd.log,确认脚本会做的改动。

2) 真正执行一次(手动触发)

确认无误后执行:

PowerShell -ExecutionPolicy Bypass -File "C:\Scripts\AutoSortDownloads.ps1" -Mode apply -DateMode Monthly

3) 定时自动化(每天晚间自动整理)

用任务计划程序每天某个时间运行(例如 23:30):

通过 schtasks 创建每天 23:30 运行任务(当前用户):

schtasks /Create /SC DAILY /TN "AutoSortDownloads" /TR "PowerShell -ExecutionPolicy Bypass -File \"C:\Scripts\AutoSortDownloads.ps1\" -Mode apply -DateMode Monthly" /ST 23:30

或在任务计划程序 GUI 中创建:创建任务 → 常规填写名称 → 触发器设置为每天23:30 → 操作选择启动程序 powershell.exe,参数填写 -ExecutionPolicy Bypass -File "C:\Scripts\AutoSortDownloads.ps1" -Mode apply -DateMode Monthly。

常见选项说明(可按需修改)

-DateMode:Daily 按日期(例如 Images\2025-11-10),Monthly 按月(例如 Images\2025-11)。-Exclude:脚本顶部可修改默认排除规则(例如临时下载 .crdownload、.tmp)。Mapping:在脚本中修改 $Mapping 字典来调整分类与扩展名。是否递归整理子目录:当前脚本仅整理根目录文件(避免移动已整理的子目录内文件),如需递归把 Get-ChildItem 加上 -Recurse 并排除目标子目录。去重策略:当前策略是目标存在则为移动的文件添加时间戳后再移动,避免覆盖。

测试建议(安全第一)

先在一个临时目录测试(复制几个示例文件到 C:\Temp\DownloadsTest),用 -Source 指向该目录并先运行 -Mode dryrun 查看日志。观察日志确认无问题后切换 -Mode apply。若你担心误删或移动重要文件,可先备份 Downloads 文件夹(复制到外部硬盘或压缩打包)。

常见问题解答

Q:会不会把重要未分类文件误删?A:脚本只 移动 文件,不会删除,且默认是 dryrun 模式。请务必先 dryrun。Q:能否把图片按拍照日期归档?A:可把 Get-ChildItem 中读取的 CreationTime 改为读取 EXIF 的拍摄时间(需要额外读取图片元数据)。如需我可以提供扩展示例。Q:如何处理大量小文件导致性能问题?A:可把脚本拆成批次(例如一次处理前 N 个文件),或在低峰期运行(夜间)。

小结(你将获得)

一个可复制、可定制的 PowerShell 脚本(含 dryrun)用于自动整理下载目录;一条 schtasks 命令用于每天自动执行;日志记录和防止覆盖的去重策略,保证安全可回溯。

picture loss