
Ich habe ein Skript erstellt, das bei der Massenbearbeitung von Berechtigungen innerhalb einer umfangreichen Ordnerstruktur hilft, basierend auf einer Liste in einer CSV-Datei. Das Skript funktioniert wie erwartet, aber bei mehreren Ordnern weiß ich, dass das Skript fehlschlagen und einen Fehler ausgeben sollte, weil der Ordner nicht existiert. Ich erhalte jedoch keine Ausgabe vom Skript, abgesehen von einer laufenden Liste, die mich über den aktuellen Ordner informiert. Ich habe Try-Catch versucht, aber das Skript stoppt die Verarbeitung beim ersten Fehler und ich bin nicht sicher, wie ich Catch so konstruieren soll, dass das Skript weiterläuft. Was ist der beste Weg, um die Verarbeitung des Skripts aufrechtzuerhalten, aber Fehler, von denen ich weiß, dass sie vorhanden sind, in eine Datei auszugeben, damit ich sie später überprüfen kann?
Wenn der Code beispielsweise ausgeführt wird, sollte er in den Ordnern 1 bis 3 funktionieren. Wenn Ordner 2 nicht vorhanden ist, hat Powershell einen Fehler mit dem nicht gefundenen Pfad ausgegeben und die Ausführung fortgesetzt. Ich möchte diesen Fehler in einer Datei, die später analysiert werden kann, da einige Ordner nicht der von diesem Skript geänderten Struktur folgen.
$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
}
Antwort1
Für den Umgang mit solchen Fehlern gibt es mehrere Strategien.
-ErrorAction
Die erste besteht darin , dem Befehl einen Parameter hinzuzufügen , der fehlschlagen kann.
Die zweite Möglichkeit besteht darin, den Befehl in try/catch einzuschließen:
$ProjectSub = $Project + "\Folder2"
$securityDescriptor = Get-Acl -Path $ProjectSub
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlRootFolders)
try {
Set-Acl -Path $ProjectSub -AclObject $securityDescriptor
} catch {
"Poo"
}
"Do more"
Beachten Sie, dass Sie in beiden Fällen weiterhin die Standardfehlermeldungen erhalten, die Ausführung jedoch fortgesetzt wird. Im ersten Fall wird die Ausführung zur nächsten Zeile verschoben. Beim Try/Catch wird das Catch ausgeführt (druckt „Poo“) und dann die nächste Zeile („Do More“). Sie benötigen das Try/Catch nur dann wirklich, wenn Sie nur bei einem Fehler etwas tun möchten, z. B. einige Details zur späteren Verarbeitung in einer anderen Datei speichern möchten.
In Ihrem Fall könnten Sie, vorausgesetzt, dass die Verarbeitungsliste nicht zu groß ist, ein benutzerdefiniertes Objekt im Catch erstellen, um nicht vorhandene Dateidetails in einer Variablen zu sammeln. Schreiben Sie die Variable dann am Ende des Skripts in eine Datei. Achten Sie nur darauf, dass die Variable nicht zu groß wird. Ich hatte Skripts mit Zehntausenden von Ergebnissen, die ziemlich viel Speicher verbrauchten!