我正在寻找一种方法来递归遍历我的整个文件共享(相当大的 3TB 文件)并列出我无权访问的所有文件/文件夹。由于迁移和大路径(超过 255 个字符)上的一些错误,我们发现一些文件夹/文件已丢失所有权限,需要一种方法来找到它们。目前作为域管理员用户,我无法列出权限或所有者。我可以控制它并重置权限,但我有太多文件/文件夹,我想将其输出到 CSV 文件或其他文件。
我尝试了以下方法:
get-childitem "\,\fileshare\f$\folder\etc" -recurse | get-acl
这似乎很完美,它为我提供了所有存在且具有适当权限的文件/文件夹的 ACL。但是一旦它到达我无权访问的文件夹,我就会收到以下错误:
Get-Acl : Attempted to perform an unauthorized operation.
At line:1 char:133
+ get-childitem "\,\fileshare\f$\folder\etc" -re
curse | get-acl <<<<
+ CategoryInfo : NotSpecified: (:) [Get-Acl], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetAclCommand
这些是我想要记录到 CSV/TXT 文件中的错误,并忽略所有其余权限,如果可以以每个错误一行的方式输出,那就太理想了。
只是想知道是否有人对我应该如何进行有什么想法或提示?
(请注意,上面的路径中故意有逗号,以便不解析为真实路径
\,\fileshare\f$\folder\etc)
谢谢!
答案1
将 cmdlet 特定错误捕获到文件中的更简单且更不令人困惑的方法是使用 -Errorvariable 参数。它内置于大多数 cmdlet 中。查看 $Error 变量并不可靠,因为它是一个全局变量,并且很有可能受到 powershell 进程中其他未缓解的错误的影响。
下面的代码将在 2 个日志文件中记录错误。
- gci_errors.csv - 包含枚举文件夹的错误
gacl_errors.csv — 包含枚举特定文件/文件夹的 ACL 的错误。
Get-ChildItem C:\Temp -Recurse -ErrorAction SilentlyContinue -ErrorVariable gci_errors | ForEach-Object { $_ | Get-Acl -ErrorAction SilentlyContinue -ErrorVariable gacl_errors } $gci_errors | Select-Object -ExpandProperty CategoryInfo | Export-Csv -NoTypeInformation -Path C:\Temp\gci_errors.csv $gacl_errors | Select-Object -ExpandProperty CategoryInfo | Export-Csv -NoTypeInformation -Path C:\Temp\gacl_errors.csv
我已根据您的要求将输出更改为 CSV 文件。这样更有意义,因为它更容易分析和导入以对数据运行命令。CSV 有一个名为目标它反映了导致问题的文件夹路径。您可以编写一个 cmdlet,即修复目录权限并通过管道传输到它。例如:
Import-CSV -Path c:\Temp\gci_errors.csv | Fix-DirPerms
答案2
有很多不同的方法可以做到这一点。这是我刚刚想出来的。
$Error.Clear() # This is a global variable!
$Errors = @()
$Items = Get-ChildItem C:\ -Recurse -ErrorAction SilentlyContinue
ForEach($Err In $Error)
{
$Errors += $Err.Exception
}
ForEach($Item In $Items)
{
Try
{
$Item | Get-ACL -ErrorAction SilentlyContinue | Out-Null
}
Catch
{
$Errors += "$($_.Exception.Message) $($Item.FullName)"
}
}
Write-Host $Errors.Count "errors encountered."
$Errors | Out-File errors.txt
现在,您有了一个在 Get-ChildItem 进程或 Get-ACL 进程中遇到的所有错误的简洁列表,这很重要,因为在每个操作期间都可能遇到不同的错误。您可以将 $Errors 变量通过管道传输到 CSV 或任何您想要的文件中。这可能需要很长时间才能在 3TB 网络共享上运行。考虑添加进度表。