PowerShell脚本需求:删除60天前文件且保留至少6个文件
需求与问题
我是PowerShell初学者,想写脚本实现:删除LastWriteTime超过60天的文件,但要保证每个子文件夹至少保留6个文件。
试了两种方式都没成功:
- 单独用
Where-Object时,写的Where{$._readcount -gt X -and x -and x}只会选中文件夹,选不到目标文件 - 尝试结合
Select-Object -Skip和Where-Object,但二者配合无法实现“按文件夹跳过前N个文件+过滤过期文件”的组合逻辑
以下是我试过的两条命令:
Get-ChildItem $delPath -Include *.* -File -Recurse | Sort LastWriteTime -Descending | Where-Object {!$_.PSIsContainer -and $_.LastWriteTime -lt $limit $._readcount -gt 6 } | Out-File -FilePath $workpath\$2log Get-ChildItem $delPath -Include *.* -File -Recurse | Sort LastWriteTime -Descending | Select-Object -skip 2 | Where-Object { !$_.PSIsContainer -and $_.LastWriteTime -lt $limit }
可行解决方案
核心逻辑是按文件夹分组处理——全局Skip会跳过整个目录树的前N个文件,无法满足“每个文件夹单独留6个”的要求,必须先按文件夹分组,再对每组内的文件单独筛选。
完整脚本(带日志)
# 配置参数 $limit = (Get-Date).AddDays(-60) # 60天前的时间阈值 $delPath = "C:\你的目标目录路径" $workpath = "C:\日志保存路径" $minFilesToKeep = 6 # 每个文件夹至少保留的文件数 $logFile = Join-Path $workpath "DeleteLog_$(Get-Date -Format 'yyyyMMdd').log" # 按文件夹分组处理文件 Get-ChildItem $delPath -File -Recurse | Group-Object -Property DirectoryName | # 按所在文件夹分组 ForEach-Object { # 组内文件按最后修改时间降序排序(最新的排在最前面) $sortedFiles = $_.Group | Sort-Object LastWriteTime -Descending # 跳过前N个要保留的文件,再筛选出超过60天的文件 $filesToDelete = $sortedFiles | Select-Object -Skip $minFilesToKeep | Where-Object { $_.LastWriteTime -lt $limit } # 记录日志并执行删除(测试阶段可注释Remove-Item,先验证日志) if ($filesToDelete) { $filesToDelete | ForEach-Object { "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') - 准备删除: $($_.FullName)" | Add-Content $logFile # Remove-Item $_.FullName -Force # 测试无误后取消注释启用删除 } } }
关键说明
- 用
Group-Object -Property DirectoryName实现按文件夹分组,确保每个文件夹的文件单独处理 - 每组内先按
LastWriteTime降序,保证最新的文件排在前面,Select-Object -Skip $minFilesToKeep直接跳过要保留的前6个 - 后续的
Where-Object只过滤过期文件,避免误删最新的文件(比如某文件夹过期文件不足6个时,跳过前6个后就没有要删除的内容) - 原命令中的
-Include *.*和!$_.PSIsContainer可以省略,因为-File参数已经只返回文件,无需额外过滤
内容的提问来源于stack exchange,提问作者Leon Schock
相关产品推荐
相关产品推荐

