Windows Server 2019中按用户统计回收站占用空间并生成结构化表格的最优方案
Windows Server 2019中按用户统计回收站占用空间并生成结构化表格的最优方案
我完全懂你这种困扰——生产服务器上回收站悄悄占满磁盘,用Disk Cleanup只能看自己的,直接递归扫整个C:\$Recycle.Bin又慢到离谱,还没法对应到具体用户对吧?结合我处理这类问题的经验,给你一套高效又精准的PowerShell方案,完美满足你要的用户-回收站大小表格需求。
核心思路
Windows的回收站是按用户SID(安全标识符)分目录存储的,C:\$Recycle.Bin下每个以SID命名的文件夹,就是对应用户的回收站。我们可以:
- 遍历这些SID文件夹,把SID转换成可读的用户名
- 针对每个用户的回收站目录单独计算大小(比全局递归快得多,还能避免长时间占用服务器资源)
- 整理成结构化表格输出
最优PowerShell脚本(基础版)
这个脚本兼顾准确性和效率,还能处理异常情况(比如已删除用户的SID文件夹):
# 目标磁盘的回收站路径 $recycleBinPath = 'C:\$Recycle.Bin' # 获取回收站下所有用户SID对应的文件夹(跳过非目录项) $sidFolders = Get-ChildItem -LiteralPath $recycleBinPath -Directory -Force -ErrorAction SilentlyContinue # 初始化结果存储数组 $recycleStats = @() foreach ($folder in $sidFolders) { try { # 将SID转换为用户/账户名称(支持系统账户如SYSTEM、管理员账户) $sidObj = New-Object System.Security.Principal.SecurityIdentifier($folder.Name) $userName = $sidObj.Translate([System.Security.Principal.NTAccount]).Value # 计算当前用户回收站的总大小(只统计文件,避免重复计算文件夹本身) $totalBytes = (Get-ChildItem -LiteralPath $folder.FullName -File -Force -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum # 把字节数转换成易读的格式(TB/GB/MB/KB) $readableSize = switch ($totalBytes) { { $_ -ge 1TB } { "{0:N2} TB" -f ($_ / 1TB) } { $_ -ge 1GB } { "{0:N2} GB" -f ($_ / 1GB) } { $_ -ge 1MB } { "{0:N2} MB" -f ($_ / 1MB) } default { "{0:N2} KB" -f ($_ / 1KB) } } # 把结果加入数组 $recycleStats += [PSCustomObject]@{ User = $userName Directory = "Recycle Bin (C:)" Size = $readableSize RawSize = $totalBytes # 保留原始字节数,方便排序 } } catch { # 处理无法识别的SID(比如已删除的用户账户) $recycleStats += [PSCustomObject]@{ User = "Unknown SID: $($folder.Name)" Directory = "Recycle Bin (C:)" Size = "N/A" RawSize = $null } } } # 按大小降序排序,输出美观的表格 $recycleStats | Sort-Object RawSize -Descending | Select-Object User, Directory, Size | Format-Table -AutoSize
超大型回收站优化方案(极速版)
如果你的服务器回收站特别大,用Get-ChildItem还是慢,可以换成Robocopy来计算大小——它的文件遍历效率比PowerShell原生命令高很多,几乎瞬间就能出结果:
把脚本中计算$totalBytes的部分替换成这段:
# 用Robocopy快速获取目录总大小(/L表示仅列出,不复制;/S包含子目录) $robocopyOutput = robocopy $folder.FullName NULL /L /S /NFL /NDL /BYTES /NC /NP /NJH /NJS $totalBytes = [long]($robocopyOutput | Select-String -Pattern "^\s*(\d+)\s*$").Matches.Groups[1].Value
注意事项
- 必须以管理员权限运行脚本:
C:\$Recycle.Bin是系统保护目录,普通权限无法访问其他用户的回收站文件夹 - 脚本会自动跳过权限不足的目录,不会中断执行
- 输出的表格会按大小从大到小排序,方便你快速定位占用空间最多的用户
示例输出
运行脚本后会得到你想要的结构化表格:
User Directory Size ---- --------- ---- SYSTEM Recycle Bin (C:) 300.00 TB spunky Recycle Bin (C:) 100.00 GB sergio Recycle Bin (C:) 20.00 GB admin Recycle Bin (C:) 10.00 GB rene Recycle Bin (C:) 1.00 GB
备注:内容来源于stack exchange,提问作者kindzmarauli




