É possível listar todas as permissões onde eu não tenho acesso

5

Estou procurando uma maneira de percorrer recursivamente todo o meu compartilhamento de arquivos (bastante grande de 3TB de arquivos) e listar todos os arquivos / pastas aos quais não tenho acesso. Devido a uma migração e alguns erros em caminhos grandes (mais de 255 caracteres), descobrimos que algumas pastas / arquivos perderam todas as permissões e precisam encontrar uma maneira de encontrá-las. Atualmente, como usuário administrador de domínio, não posso listar as permissões ou o proprietário. Eu posso assumir o controle e redefinir as permissões, mas eu tenho tantos arquivos / pastas que eu gostaria de enviar isso para um arquivo CSV ou algo assim.

Eu tentei o seguinte:

get-childitem "\,\fileshare\f$\folder\etc" -recurse | get-acl

Isso parece funcionar perfeitamente, me dá as ACLs de todos os arquivos / pastas que existem e possuem permissões adequadas para eles. Mas quando atinge uma pasta que não tenho acesso, recebo o seguinte erro:

Get-Acl : Attempted to perform an unauthorized operation.
At line:1 char:133
+ get-childitem "\,\fileshare\f$\folder\etc" -re
curse | get-acl <<<<
    + CategoryInfo          : NotSpecified: (:) [Get-Acl], UnauthorizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetAclCommand

Estes são os erros que eu gostaria de registrar em um arquivo CSV / TXT, e ignorar todas as permissões restantes, seria ideal se isso pudesse ser gerado em mais uma linha por erro também.

Apenas imaginando se alguém tem uma ideia ou sugestão de como devo proceder?

(Por favor, note os caminhos acima têm vírgulas neles de propósito para não resolver para um caminho real

\,\fileshare\f$\folder\etc)

Obrigado!

    
por Jason Gilmore 13.05.2013 / 23:31

2 respostas

2

Uma maneira mais fácil e menos confusa de capturar erros específicos do cmdlet em um arquivo é usando o parâmetro -Errorvariable. Ele é construído na maioria dos cmdlets. Não é confiável examinar a variável $ Error, pois ela é uma variável global e tem uma grande chance de ser corada por outros erros não mitigados no processo PowerShell.

O código abaixo registrará os erros em dois arquivos de log.

  1. gci_errors.csv - Contém erros enumerando as pastas
  2. gacl_errors.csv - Contém erros ao enumerar a ACL em um arquivo / pasta específico.

    Get-ChildItem C:\Temp -Recurse -ErrorAction SilentlyContinue -ErrorVariable gci_errors | ForEach-Object {
    
        $_ | Get-Acl -ErrorAction SilentlyContinue -ErrorVariable gacl_errors
    }
    
    $gci_errors | Select-Object -ExpandProperty CategoryInfo | Export-Csv -NoTypeInformation -Path C:\Temp\gci_errors.csv 
    $gacl_errors | Select-Object -ExpandProperty CategoryInfo | Export-Csv -NoTypeInformation -Path C:\Temp\gacl_errors.csv
    

Alterei a saída para um arquivo CSV conforme sua exigência. Faz mais sentido, pois é mais fácil analisar e importar para executar comandos nos dados. O CSV tem um cabeçalho chamado Target , que reflete o caminho da pasta que está causando problemas. Você pode escrever um cmdlet, ou seja, Fix-DirPerms e canalizar para ele. Algo como:

    Import-CSV -Path c:\Temp\gci_errors.csv | Fix-DirPerms
    
por 14.05.2013 / 12:19
1

Existem várias maneiras diferentes de fazer isso. Aqui está algo que eu acabei de fazer.

$Error.Clear()      # This is a global variable!
$Errors = @()
$Items = Get-ChildItem C:\ -Recurse -ErrorAction SilentlyContinue
ForEach($Err In $Error)
{
    $Errors += $Err.Exception
}
ForEach($Item In $Items)
{
    Try
    {
        $Item | Get-ACL -ErrorAction SilentlyContinue | Out-Null
    }
    Catch
    {
        $Errors += "$($_.Exception.Message) $($Item.FullName)"
    }
}    
Write-Host $Errors.Count "errors encountered."
$Errors | Out-File errors.txt

Agora você tem uma lista clara de todos os erros encontrados no processo Get-ChildItem ou no processo Get-ACL, o que é importante porque erros distintos podem ser encontrados durante cada operação. Você pode enviar a variável $ Errors para um CSV ou o que você quiser. Isso provavelmente levará muito tempo para ser executado em um compartilhamento de rede de 3TB. Considere adicionar um medidor de progresso.

    
por 14.05.2013 / 00:07