Gere um log de erros do Powershell

Gere um log de erros do Powershell

Criei um script para auxiliar na edição em massa de permissões dentro de uma extensa estrutura de pastas, baseada em uma lista dentro de um arquivo CSV. O script funciona conforme o esperado, mas para várias pastas, sei que o script deve falhar e gerar um erro porque a pasta não existe. No entanto, não estou obtendo nenhuma saída do script, além de uma lista em execução, preciso me notificar sobre a pasta atual. Tentei o Try-Catch, mas o script interrompe o processamento no primeiro erro e não tenho certeza de como projetar o Catch para manter o script funcionando. Qual é a melhor maneira de manter o processamento do script, mas sei que existem erros de saída em um arquivo para que eu possa revisá-los posteriormente?

Por exemplo, quando o código for executado, ele deverá funcionar nas pastas 1-3. Se a pasta 2 não existisse, o Powershell costumava gerar um erro com o caminho que não conseguia encontrar e continuaria. Gostaria que esse erro em um arquivo fosse analisado posteriormente, pois algumas pastas não seguem a estrutura modificada por este script.

$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

}

Responder1

Existem várias estratégias para lidar com erros como esse.

A primeira é adicionar um -ErrorActionparâmetro ao comando que pode falhar.

A segunda é agrupar o comando em try/catch:

$ProjectSub = $Project + "\Folder2"
$securityDescriptor = Get-Acl -Path $ProjectSub
$securityDescriptor.SetSecurityDescriptorSddlForm($sddlRootFolders)
try {
    Set-Acl -Path $ProjectSub -AclObject $securityDescriptor
} catch {
    "Poo"
}
"Do more"

Observe que em ambos os casos, você ainda receberá as mensagens de erro padrão, mas a execução continuará. No primeiro caso, a execução passa para a próxima linha. No try/catch, o catch é executado (imprime "Poo") e depois a próxima linha ("Do More"). Você realmente só precisa de try/catch se quiser fazer algo apenas em caso de falha, como salvar alguns detalhes em um arquivo diferente para processamento posterior.

No seu caso, supondo que a lista de processamento não seja muito grande, você poderia criar um objeto personalizado no catch para acumular detalhes de arquivos inexistentes em uma variável. Então, no final do script, grave a variável em um arquivo. Apenas tome cuidado com a variável ficando muito grande. Tive scripts com dezenas de milhares de resultados que consumiram grandes quantidades de memória!

informação relacionada