解决Get-ChildItem导出超7年文件时的内存溢出问题
解决PowerShell递归导出旧文件内存溢出问题
完全可以通过Export-Csv -Append结合逐行处理的方式解决内存溢出问题。原脚本的问题在于管道会将所有筛选后的文件对象一次性缓存到内存中,再批量写入CSV,当文件数量极大时就会导致内存耗尽。改用逐行处理后,每个文件对象生成后立即写入CSV,不会在内存中堆积大量数据。
修改后的脚本
$csvOutputPath = "C:\OldFiles.csv" $sevenYearsAgo = (Get-Date).AddYears(-7) # 先清理已存在的输出文件,避免追加旧数据 if (Test-Path $csvOutputPath) { Remove-Item $csvOutputPath -Force } # 逐行处理文件并追加写入CSV Get-ChildItem "D:\Shares\" -Recurse -File | Where-Object { $_.LastWriteTime -lt $sevenYearsAgo } | ForEach-Object { [PSCustomObject]@{ FullName = $_.FullName LastWriteTime = $_.LastWriteTime Length = [math]::Round($_.Length / 1MB, 2) # 保留两位小数提升可读性 } | Export-Csv -Path $csvOutputPath -Append -NoTypeInformation }
关键优化点
- 提前计算截止日期:将
(Get-Date).AddYears(-7)赋值给变量$sevenYearsAgo,避免每次循环重复计算,提升执行效率。 - 逐行写入CSV:通过
ForEach-Object逐个处理文件对象,每个对象生成后立即通过-Append写入CSV,内存占用始终保持在极低水平。 - 可选优化:对文件大小保留两位小数,让导出的CSV数据更易读。
额外提示
如果共享目录包含数百万级别的文件,可进一步结合Get-ChildItem的-Filter参数提前过滤文件类型,减少需要处理的对象数量;或者使用-Depth参数分层次遍历,进一步降低内存压力。
内容的提问来源于stack exchange,提问作者NetAdmin
相关产品推荐
相关产品推荐

