删除大量文件而不会耗尽内存

时间:2017-04-15 22:54:48

标签: powershell get-childitem

我们有COTS应用程序可以创建报告并且永远不会删除它。所以我们需要开始清理它。我开始做一个foreach并且当它获得高达50万个文件时,服务器上的内存不足(36GB)。搜索后,似乎你可以改变它

Get-ChildItem -path $Path -recurse | foreach {

它不会通过记忆但一次处理每个项目。在内存不足之前,我可以获得1.4亿个文件。

Clear-Host
#Set Age to look for
$TimeLimit = (Get-Date).AddMonths(-4)
$Path = "D:\CC\LocalStorage"

$TotalFileCount = 0
$TotalDeletedCount = 0

Get-ChildItem -Path $Path -Recurse | foreach {
    if ($_.LastWriteTime -le $TimeLimit) {
        $TotalDeletedCount += 1
        $_.Delete()
    }
    $TotalFileCount += 1

    $FileDiv = $TotalFileCount % 10000
    if ($FileDiv -eq 0 -and $TotalFileCount -ne 0) {
        $TF = [string]::Format('{0:N0}', $TotalFileCount)
        $TD = [string]::Format('{0:N0}', $TotalDeletedCount)
        Write-Host "Files Scanned : " -ForegroundColor Green  -NoNewline
        Write-Host "$TF" -ForegroundColor Yellow    -NoNewline
        Write-Host " Deleted: " -ForegroundColor Green  -NoNewline
        Write-Host "$TD" -ForegroundColor Yellow  
    }

有更好的方法吗?我唯一的想法是不使用-Recurse命令,而是创建自己的函数,为每个目录调用自己。

编辑:

我使用了第一个答案中提供的代码,但它没有解决问题。记忆力仍在增长。

$limit = (Get-Date).Date.AddMonths(-3)
$totalcount  = 0
$deletecount = 0
$Path = "D:\CC\"

Get-ChildItem -Path $Path -Recurse -File |  Where-Object { $_.LastWriteTime -lt $limit } |  Remove-Item -Force

1 个答案:

答案 0 :(得分:4)

使用ForEach-Object和管道实际上应该防止代码内存不足。如果您仍然遇到OOM异常,我怀疑您在代码中正在做一些对抗此效果的事情,而您没有告诉我们。

话虽如此,您应该能够使用以下内容清理数据目录:

$limit = (Get-Date).Date.AddMonths(-4)

Get-ChildItem -Path $Path -Recurse -File |
  Where-Object { $_.LastWriteTime -lt $limit } |
  Remove-Item -Force -WhatIf

验证一切正常后,删除-WhatIf开关。

如果您需要总文件数和已删除文件数,请添加如下计数器:

$totalcount  = 0
$deletecount = 0

Get-ChildItem -Path $Path -Recurse -File |
  ForEach-Object { $totalcount++; $_ } |
  Where-Object { $_.LastWriteTime -lt $limit } |
  ForEach-Object { $deletecount++; $_ } |
  Remove-Item -Force -WhatIf

当您批量处理大量文件时,我不建议将状态信息打印到控制台。输出可能会显着减慢处理速度。如果您必须拥有该信息,请将其写入日志文件并单独归档该文件。