PowerShell递归统计文件夹文件数与Windows显示不符求助
PowerShell文件统计与资源管理器计数不一致的解决建议
问题描述
我使用以下PowerShell脚本将指定UNC路径映射为驱动器,递归统计目标文件夹的文件数量,当文件数超过设定阈值时发送告警邮件。但脚本统计的文件数始终与Windows资源管理器显示的文件数存在差异,恳请提供解决建议。
脚本内容
<# ------------------------C-O-U-N-T-&-R-E-P-O-R-T----------------------- #> # 变量定义 $DriveLetter = "N" # 网络驱动器盘符 $NetworkPath = "\\10.1.10.10\ebys_tmp" $Username = "svc_userInfo" $Password = ConvertTo-SecureString "passw0rD!!" -AsPlainText -Force $LogServer = "contoso-eposta-01" # 远程服务器名称 $eventLogName = "Application" # 事件日志名称 $eventLogSource = "EBYS FileCount" # 事件日志来源 $LogServerUsername = "contoso\svc_userinfo" # 远程服务器用户名 $LogServerPassword = ConvertTo-SecureString "Passw0rD!!" -AsPlainText -Force # 远程服务器密码 $LogServerCredential = New-Object System.Management.Automation.PSCredential($remoteUsername, $remotePassword) try { # 定义网络驱动器访问凭据 $Credential = New-Object System.Management.Automation.PSCredential ($Username, $Password) # 检查驱动器盘符是否已存在 $existingDrive = Get-PSDrive -Name $DriveLetter -ErrorAction SilentlyContinue # 如果盘符已存在 if ($existingDrive -ne $null) { Write-Host "驱动器 $DriveLetter 已存在,直接进入统计步骤。" } else { # 将UNC路径映射为网络驱动器 New-PSDrive -Name $DriveLetter -PSProvider FileSystem -Root $NetworkPath -Credential $Credential -Persist Write-Host "驱动器 $DriveLetter 映射成功。" } # 递归统计文件数量 $fileCount = (Get-ChildItem -Recurse -File -Exclude 'RtBackup').Count $fileLimit = 30000 <# 远程服务器创建事件日志记录 $remoteServer = "contoso-eposta-01" # 远程服务器名称 $eventLogName = "Application" # 事件日志名称 $eventLogSource = "EBYS FileCount" # 事件日志来源 $remoteUsername = "contoso.org\svc_ebystmpinfo" # 远程服务器用户名 $remotePassword = ConvertTo-SecureString "Passw0rD!!" -AsPlainText -Force # 远程服务器密码 $remoteCredential = New-Object System.Management.Automation.PSCredential($remoteUsername, $remotePassword) #> if ($fileCount -ge $fileLimit) { # SMTP服务器与邮件设置 $smtpUsername = "svc_userinfo" $smtpPassword = ConvertTo-SecureString "Passw0rD!!" -AsPlainText -Force $smtpCredential = New-Object System.Management.Automation.PSCredential ($smtpUsername, $smtpPassword) $emailFrom = "testuser@contoso.org" $emailTo = "testuser2@contoso.org" $emailSubject = "EBYS TMP FOLDER MONITOR" $emailBody = @" <!DOCTYPE html> <html> <head> <style> table { width:450px; border: 1px solid #b3adad; border-collapse: collapse; padding: 5px; } table th { border: 1px solid #b3adad; padding: 5px; background: #ffbb00; color: #313030; } table td { border: 1px solid #b3adad; text-align: center; padding: 5px; background: #ffffff; color: #313030; } </style> </head> <body> <table> <thead> <tr> <th colspan="2">CONTOSO ORG - 系统服务</th> </tr> </thead> <tbody> <tr> <td>允许的最大文件数:</td> <td>$fileLimit</td> </tr> <tr> <td>当前文件数:</td> <td>$fileCount</td> </tr> <tr> <td colspan="2">$NetworkPath 文件夹中的文件数已超过设定阈值 $fileLimit,当前文件数为: $fileCount</td> </tr> </tbody> </table> </body> </html> "@ # 发送邮件 Send-MailMessage -To $emailTo -From $emailFrom -Subject $emailSubject -Credential $smtpCredential -SmtpServer "ibb-eposta-01.ibb.net" -Body $emailBody -BodyAsHtml -Encoding UTF8 } } catch { Write-Host "发生错误。" <# 远程服务器创建事件日志记录 $remoteServer = "contoso-eposta-01" # 远程服务器名称 $eventLogName = "Application" # 事件日志名称 $eventLogSource = "EBYS FileCount" # 事件日志来源 $remoteUsername = "contoso.org\svc_userinfo" # 远程服务器用户名 $remotePassword = ConvertTo-SecureString "passwOrDHere!!" -AsPlainText -Force # 远程服务器密码 $remoteCredential = New-Object System.Management.Automation.PSCredential($remoteUsername, $remotePassword) #> } finally { Write-EventLog }
解决建议
排除规则错误:脚本中
-Exclude 'RtBackup'仅会排除名为RtBackup的文件,而非文件夹。如果需要排除RtBackup文件夹内的所有文件,应改用路径过滤:$fileCount = (Get-ChildItem -Recurse -File | Where-Object { $_.FullName -notmatch '\\RtBackup\\' }).Count未包含隐藏/系统文件:Windows资源管理器默认可能显示隐藏和系统文件,但
Get-ChildItem默认不会统计这些文件。添加-Force参数即可获取全部文件:$fileCount = (Get-ChildItem -Recurse -File -Force | Where-Object { $_.FullName -notmatch '\\RtBackup\\' }).Count权限差异:脚本使用
svc_userInfo账号访问,可能没有部分子文件夹的权限,导致统计遗漏;而资源管理器使用当前登录用户权限,可访问更多内容。可添加错误捕获查看无法访问的路径:Get-ChildItem -Recurse -File -Force -ErrorAction SilentlyContinue -ErrorVariable accessErrors if ($accessErrors) { Write-Host "无法访问的路径:" $accessErrors | ForEach-Object { Write-Host $_.TargetObject } }网络映射延迟:刚完成驱动器映射就立即统计,可能因网络延迟导致部分文件未加载。可添加短暂延迟:
Start-Sleep -Seconds 5资源管理器缓存:资源管理器可能使用缓存的计数,并非实时统计。按F5刷新资源管理器后再对比数值。
直接访问UNC路径:映射驱动器可能因权限或缓存导致统计偏差,直接访问UNC路径更准确,无需映射驱动器:
$fileCount = (Get-ChildItem -Path $NetworkPath -Recurse -File -Force -Credential $Credential | Where-Object { $_.FullName -notmatch '\\RtBackup\\' }).Count
内容的提问来源于stack exchange,提问作者deadp1XL
相关产品推荐
相关产品推荐

