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

Powershell 删除大量文件而不会耗尽内存,powershell,get-childitem,Powershell,Get Childitem,我们有一个COTS应用程序,它可以创建报告,并且从不删除报告。所以我们需要开始清理它。我开始做foreach,当36GB的服务器上有5000万个文件时,它的内存就会耗尽。在搜索之后,你似乎可以像这样改变它 Get-ChildItem -path $Path -recurse | foreach { 它不会遍历内存,而是一次处理每个项目。在内存耗尽之前,我可以访问1.4亿个文件 Clear-Host #Set Age to look for $TimeLimit = (Get-Date).Add

我们有一个COTS应用程序,它可以创建报告,并且从不删除报告。所以我们需要开始清理它。我开始做foreach,当36GB的服务器上有5000万个文件时,它的内存就会耗尽。在搜索之后,你似乎可以像这样改变它

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
使用ForEach对象和管道实际上应该可以防止代码内存不足。如果您仍然收到OOM异常,我怀疑您在代码中做了一些事情来抵消这种影响,您没有告诉我们

话虽如此,您应该能够通过以下方式清理数据目录:

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

Get-ChildItem -Path $Path -Recurse -File |
  Where-Object { $_.LastWriteTime -lt $limit } |
  Remove-Item -Force -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
确认一切正常后,卸下-WhatIf开关

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

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

Get-ChildItem -Path $Path -Recurse -File |
  Where-Object { $_.LastWriteTime -lt $limit } |
  Remove-Item -Force -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

我不建议在批量处理大量文件时将状态信息打印到控制台。输出可能会显著降低处理速度。如果您必须拥有该信息,请将其写入日志文件,并分别跟踪该文件。

该函数与我拥有的函数完全相同。我刚刚删除了我在函数前后发布的消息。至于输出,我同意这会减慢处理速度,这就是为什么我每10000次才做一次,但这只是为了让我在它从OOM死亡之前注意它在哪里。我将很快测试你的代码。将需要到明天,因为有这么多的文件,但谢谢你。好的,所以我使用了没有任何修改的第一个脚本,它仍然消耗内存。我不能让它在消耗全部36 GB内存之前运行整个文件夹,因为它无法复制。我用1000000个随机生成的文件测试了上面的代码,内存消耗没有明显增加。我对一百万个文件没有任何问题,也不会增加很多。但是1.4亿占用了32G的内存。那么,只需批量删除文件即可。这毕竟是一个一次性的清理任务,对吗?如果目标是自动化,那么应该将Write Host更改为Write Verbose。看,这是一个具体的任务。我明白写长篇大论的目的,但因为只是我用它来快速获取信息,所以没关系。