Я создал скрипт, чтобы помочь в массовых правах на редактирование внутри обширной структуры папок, основываясь на списке внутри файла 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

1

Есть несколько стратегий для обработки таких ошибок.

Первый - добавить параметр -ErrorAction в команду, которая может завершиться ошибкой.

Второй - обернуть команду в 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"). Попробовать / поймать вам действительно нужно только в том случае, если вы хотите что-то сделать только при сбое, например сохранить некоторые детали в другом файле для последующей обработки.

В вашем случае, предполагая, что список обработки не слишком велик, вы можете создать пользовательский объект в улове, чтобы накапливать несуществующие подробности файла в переменную. Затем в конце скрипта запишите переменную в файл. Просто следите за тем, чтобы переменная становилась слишком большой. У меня были сценарии с десятками тысяч результатов, которые занимают довольно много памяти!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .