
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
이와 같은 오류를 처리하기 위한 몇 가지 전략이 있습니다.
첫 번째는 -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")이 실행됩니다. 나중에 처리하기 위해 일부 세부 정보를 다른 파일에 저장하는 등 실패 시에만 작업을 수행하려는 경우 try/catch가 실제로 필요합니다.
귀하의 경우 처리 목록이 너무 크지 않다고 가정하면 catch에 사용자 정의 개체를 만들어 존재하지 않는 파일 세부 정보를 변수에 축적할 수 있습니다. 그런 다음 스크립트 끝에서 변수를 파일에 씁니다. 변수가 너무 커지는 것을 주의하세요. 수만 개의 결과가 포함된 스크립트가 상당히 많은 양의 메모리를 사용했습니다!