在日常工作中,我们经常会遇到需要统一修改文件时间戳的场景。比如你从旧硬盘备份了大量文件到新电脑,所有文件的"修改日期"都变成了拷贝当天的日期,这会导致按时间排序查找文件时出现混乱。又或者你在整理照片库时,希望将所有图片的修改时间调整为拍摄日期。
Windows资源管理器虽然可以手动修改单个文件的属性,但面对成百上千个文件时,这种操作效率极低。这时候就需要借助PowerShell这样的强大工具来实现批量自动化处理。
在开始操作前,建议先确认你的PowerShell版本。虽然本文介绍的命令在PowerShell 5.1及以上版本都能运行,但新版本会有更好的性能和更多功能。打开PowerShell输入:
powershell复制$PSVersionTable.PSVersion
如果显示版本低于5.1,建议通过Windows Update升级系统。Windows 10 20H2及以后版本都预装了PowerShell 7+。
首次运行脚本时可能会遇到执行策略限制。以管理员身份运行PowerShell,输入以下命令查看当前策略:
powershell复制Get-ExecutionPolicy
如果返回"Restricted",需要临时修改策略:
powershell复制Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
这样只对当前会话生效,不会影响系统安全设置。
这是最直观的操作流程,特别适合需要反复检查目录内容的情况:
powershell复制# 切换到目标目录(注意路径中的空格需要用引号包裹)
cd "D:\Project Files\2023 Archive"
# 列出目录内容确认位置正确
Get-ChildItem
# 执行时间修改命令
Get-ChildItem -Recurse -File | ForEach-Object {
$_.LastWriteTime = Get-Date
Write-Host "已更新: $($_.FullName)" -ForegroundColor Green
}
重要提示:
-Recurse参数会递归处理所有子目录,如果只想修改当前目录文件,去掉这个参数即可。
当你知道确切路径时,可以直接指定路径执行,省去导航步骤:
powershell复制Get-ChildItem -Path "E:\Backup\Photos" -Recurse -File | ForEach-Object {
$_.LastAccessTime = Get-Date
$_.LastWriteTime = Get-Date
$_.CreationTime = (Get-Date).AddDays(-30) # 创建时间设为30天前
Write-Host "已更新: $($_.Name)" -ForegroundColor Cyan
}
这个增强版命令同时修改了三个时间属性:
如果想将所有文件时间设为某个特定日期(如2020年1月1日):
powershell复制$customDate = Get-Date "2020-01-01 08:00:00"
Get-ChildItem -Path "D:\Data" -Recurse -File | ForEach-Object {
$_.LastWriteTime = $customDate
}
只修改特定扩展名的文件(如所有.jpg图片):
powershell复制Get-ChildItem -Path "D:\Photos" -Recurse -File -Include "*.jpg","*.jpeg" | ForEach-Object {
$_.LastWriteTime = (Get-Date "2018-01-01")
}
如果需要保持文件之间的相对时间关系:
powershell复制$baseDate = Get-Date "2022-01-01"
Get-ChildItem -Path "D:\Project" -Recurse -File | ForEach-Object {
$timeDiff = $_.LastWriteTime - $_.CreationTime
$_.LastWriteTime = $baseDate + $timeDiff
$_.CreationTime = $baseDate
}
虽然时间戳修改不会影响文件内容,但建议:
powershell复制Get-ChildItem -Path "D:\Docs" -Recurse -File |
Select-Object FullName, CreationTime, LastWriteTime |
Export-Csv -Path "C:\timestamps_backup.csv" -NoTypeInformation
遇到"拒绝访问"错误时:
powershell复制Takeown /F "D:\ProtectedFolder" /R /D Y
icacls "D:\ProtectedFolder" /grant Administrators:F /T
处理数十万文件时:
powershell复制$files = Get-ChildItem -Path "D:\BigData" -Recurse -File
for($i=0; $i -lt $files.Count; $i+=1000) {
$files[$i..($i+999)] | ForEach-Object {
$_.LastWriteTime = Get-Date
}
Write-Progress -Activity "Processing" -Status "$i of $($files.Count)" -PercentComplete ($i/$files.Count*100)
}
powershell复制# 随机检查5个文件
Get-ChildItem -Path "D:\Target" -Recurse -File |
Get-Random -Count 5 |
Select-Object Name, LastWriteTime
powershell复制$report = Get-ChildItem -Path "D:\Project" -Recurse -File |
Select-Object FullName, @{Name="OldTime";Expression={$_.LastWriteTime}}, @{Name="NewTime";Expression={Get-Date}}
$report | Export-Csv -Path "C:\timestamp_changes.csv" -NoTypeInformation
在目标文件夹中:
code复制修改日期:今天
将照片时间设为EXIF中的拍摄时间:
powershell复制Add-Type -AssemblyName System.Drawing
Get-ChildItem -Path "D:\Photos" -Recurse -File -Include "*.jpg","*.png" | ForEach-Object {
$img = [System.Drawing.Image]::FromFile($_.FullName)
try {
$propItem = $img.GetPropertyItem(36867) # 36867是拍摄时间EXIF标签
$dateStr = [System.Text.Encoding]::ASCII.GetString($propItem.Value).Trim()
$dateTaken = [datetime]::ParseExact($dateStr, "yyyy:MM:dd HH:mm:ss", $null)
$_.LastWriteTime = $dateTaken
} catch {
Write-Warning "无法读取 $($_.Name) 的EXIF数据"
} finally {
$img.Dispose()
}
}
让所有文档显示最后版本更新时间:
powershell复制$verDate = Get-Date "2023-06-15"
Get-ChildItem -Path "D:\ProjectDocs" -Recurse -File -Include "*.docx","*.xlsx","*.pptx" | ForEach-Object {
$_.LastWriteTime = $verDate
}
在备份脚本中加入时间戳重置:
powershell复制# 备份函数
function Backup-Folder {
param(
[string]$Source,
[string]$Destination
)
# 复制文件
Robocopy $Source $Destination /MIR /NP /R:3 /W:5
# 统一修改时间
Get-ChildItem -Path $Destination -Recurse -File | ForEach-Object {
$_.LastWriteTime = Get-Date
}
}
# 调用示例
Backup-Folder -Source "D:\Work" -Destination "E:\Backup\Work"