
CSV ファイル内のリストに基づいて、広範なフォルダー構造内のアクセス許可を一括編集するスクリプトを作成しました。スクリプトは期待どおりに動作しますが、いくつかのフォルダーでは、フォルダーが存在しないため、スクリプトが失敗してエラーをスローするはずです。ただし、現在のフォルダーを通知する必要がある実行リストを除いて、スクリプトからの出力はありません。Try-Catch を試しましたが、スクリプトは最初のエラーで処理を停止し、スクリプトを継続するために Catch をどのように設計すればよいかわかりません。スクリプトの処理を継続しながら、存在がわかっているエラーをファイルに出力して後で確認できるようにする最適な方法は何ですか?
たとえば、コードを実行すると、フォルダー 1 ~ 3 で機能するはずです。フォルダー 2 が存在しない場合、Powershell は、見つけることができなかったパスでエラーをスローし、続行していました。一部のフォルダーはこのスクリプトによって変更された構造に従わないため、後で解析するファイル内のエラーを希望します。
$CSV=Import-Csv "C:\ProjectList.csv"
ForEach ($Entry in $CSV)
{
$ProjectNumber = $Entry.Projects
$Project = "$ProjectMain\$ProjectNumber"
Write-Host $Project #Writes out current project being processed
#sddl defines
$sddlProject = 'D:PAI(D;CI;DCLCSDWDWO;;;DU)(D;CI;DCLCSDWDWO;;;S-1-5-21-513)(A;OICI;FA;;;BA)(A;OICIIO;FA;;;CO)(A;OICI;FA;;;SY)(A;OICI;FA;;;DA)(A;OICI;0x1200a9;;;DU)(A;OICI;FA;;;S-1-5-21-512)(A;OICI;0x1200a9;;;S-1-5-21-513)'
$sddlRootFolders = 'D:PAI(D;;SDWDWO;;;DU)(D;;SDWDWO;;;S-1-5-21-513)(A;OICIIO;FA;;;CO)(A;OICI;FA;;;SY)(A;OICI;FA;;;DA)(A;OICI;0x1301bf;;;DU)(A;OICI;FA;;;BA)(A;OICI;FA;;;S-1-5-21-512)(A;OICI;0x1301bf;;;S-1-5-21-513)'
$sddlCommon = 'D:AI(A;ID;FA;;;BA)(A;OICIIOID;FA;;;CO)(A;OICIID;FA;;;SY)(A;OICIID;FA;;;DA)(A;OICIID;0x1301bf;;;DU)(A;OICIIOID;FA;;;BA)(A;OICIID;FA;;;S-1-5-21-512)(A;OICIID;0x1301bf;;;S-1-5-21-513)'
$sddlMGMT = 'D:PAI(A;OICI;0x1301bf;;;S-1-5-21-1501)(A;OICIIO;FA;;;CO)(A;OICI;FA;;;SY)(A;OICI;0x1301bf;;;S-1-5-21-12461)(A;OICI;0x1301bf;;;S-1-5-21-12462)(A;OICI;0x1301bf;;;S-1-5-21-12463)(A;OICI;0x1301bf;;;S-1-5-21-12464)(A;OICI;0x1301bf;;;S-1-5-21-12465)(A;OICI;0x1301bf;;;S-1-5-21-12466)(A;OICI;FA;;;DA)(A;OICI;0x1301bf;;;S-1-5-21-1486)(A;OICI;0x1301bf;;;S-1-5-21-1487)(A;OICI;FA;;;S-1-5-21-512)(A;OICI;FA;;;BA)'
$sddlFiles = 'D:AI(A;ID;FA;;;BA)(A;ID;FA;;;SY)(A;ID;FA;;;DA)(A;ID;0x1301bf;;;DU)(A;ID;FA;;;S-1-5-21-512)(A;ID;0x1301bf;;;S-1-5-21-513)'
#Apply ACL to main folder
$securityDescriptor = Get-Acl -Path $Project
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlProject)
Set-Acl -Path $Project -AclObject $securityDescriptor
#Apply ACL to the top tier folders
$ProjectSub = $Project + "\Folder1"
$securityDescriptor = Get-Acl -Path $ProjectSub
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlRootFolders)
Set-Acl -Path $ProjectSub -AclObject $securityDescriptor
$ProjectSub = $Project + "\Folder2"
$securityDescriptor = Get-Acl -Path $ProjectSub
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlRootFolders)
Set-Acl -Path $ProjectSub -AclObject $securityDescriptor
$ProjectSub = $Project + "\Folder3"
$securityDescriptor = Get-Acl -Path $ProjectSub
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlRootFolders)
Set-Acl -Path $ProjectSub -AclObject $securityDescriptor
#Apply ACL to MGMT folders
$ProjectSub = $Project + "\Folder9"
$ProjectDiscSub = $ProjectSub + "\MGMT"
$securityDescriptor = Get-Acl -Path $ProjectDiscSub
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlMGMT)
Set-Acl -Path $ProjectDiscSub -AclObject $securityDescriptor
#Apply ACL to MGMT inside folders
$ProjectDiscSub = $Project + "\Folder1\MGMT"
$securityDescriptor = Get-Acl -Path $ProjectDiscSub
$sddlMGMTSub = 'D:PAI(D;;SDWDWO;;;S-1-5-21-12471)(D;;SDWDWO;;;S-1-5-21-1497)(A;OICIIO;FA;;;CO)(A;OICI;FA;;;SY)(A;OICI;0x1301bf;;;S-1-5-21-12471)(A;OICI;FA;;;DA)(A;OICI;0x1301bf;;;S-1-5-21-1497)(A;OICI;FA;;;S-1-5-21-512)(A;OICI;FA;;;BA)'
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlMGMTSub)
Set-Acl -Path $ProjectDiscSub -AclObject $securityDescriptor
$ProjectDiscSub = $Project + "\Folder3\MGMT"
$securityDescriptor = Get-Acl -Path $ProjectDiscSub
$sddlMGMTSub = 'D:PAI(D;;SDWDWO;;;S-1-5-21-12469)(D;;SDWDWO;;;S-1-5-21-1501)(A;OICIIO;FA;;;CO)(A;OICI;FA;;;SY)(A;OICI;0x1301bf;;;S-1-5-21-12469)(A;OICI;FA;;;DA)(A;OICI;0x1301bf;;;S-1-5-21-1501)(A;OICI;FA;;;S-1-5-21-512)(A;OICI;FA;;;BA)'
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlMGMTSub)
Set-Acl -Path $ProjectDiscSub -AclObject $securityDescriptor
}
答え1
このようなエラーを処理するための戦略はいくつかあります。
1 つ目は、-ErrorAction
失敗する可能性があるコマンドにパラメータを追加することです。
2 番目は、コマンドを try/catch でラップすることです。
$ProjectSub = $Project + "\Folder2"
$securityDescriptor = Get-Acl -Path $ProjectSub
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlRootFolders)
try {
Set-Acl -Path $ProjectSub -AclObject $securityDescriptor
} catch {
"Poo"
}
"Do more"
どちらの場合も、標準エラー メッセージは表示されますが、実行は継続されることに注意してください。前者の場合、実行は次の行に移動します。try/catch では、catch が実行され (「Poo」が出力されます)、次に次の行 (「Do More」) が実行されます。try/catch が実際に必要なのは、後で処理するために詳細を別のファイルに保存するなど、失敗した場合にのみ何かを実行する場合のみです。
あなたの場合、処理リストが大きすぎないと仮定すると、catch でカスタム オブジェクトを作成し、存在しないファイルの詳細を変数に蓄積することができます。次に、スクリプトの最後で、変数をファイルに書き込みます。変数が大きくなりすぎないように注意してください。何万もの結果を持つスクリプトで、かなり大量のメモリを消費したことがあります。