ファイル共有全体(かなり大きな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)
ありがとう!
コマンドレット固有のエラーをファイルにトラップする簡単で混乱の少ない方法は、-Errorvariableパラメーターを使用することです。ほとんどのコマンドレットに組み込まれています。 $ Error変数はグローバル変数であり、Powershellプロセスで他の緩和されていないエラーによって汚染される可能性が高いため、$ Error変数を確認することは信頼できません。
以下のコードは、2つのログファイルにエラーを記録します。
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には、問題の原因となっているフォルダパスを反映するTargetという列ヘッダーがあります。コマンドレット、つまりFix-DirPermsを記述して、それにパイプすることができます。何かのようなもの:
Import-CSV -Path c:\Temp\gci_errors.csv | Fix-DirPerms
これを行うには、さまざまな方法があります。これが私が調理したものです。
$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のネットワーク共有で実行するにはおそらく長い時間がかかります。プログレスメーターを追加することを検討してください。