Windows PowerShellPermissões Shell

Don Jones

Faça download do código deste artigo: PowerShell2008_02.exe (151KB)

Ao discutir o Windows PowerShell, muitas vezes me perguntam sobre permissões, especialmente se e como o shell permite a automação de alterações a permissões. Permissões de arquivo são, talvez, a solicitação mais comum, embora permissões de diretório e registro também surjam com freqüência. Em se tratando de permissões e de quase

todas as interfaces de linha de comando ou script (incluindo o Windows PowerShellTM e o VBScript), tenho boas e más notícias.

As más notícias são que as permissões no Windows® são simplesmente intrinsecamente complicadas e não há muito o que o Windows PowerShell possa fazer para corrigir isso. O problema tem origem no fato de, em um sistema operacional Windows, há vários objetos em se tratando de permissões, independentemente de se você está examinando o sistema de arquivos, o Active Directory®, o registro ou quase qualquer outra coisa.

Em primeiro lugar, há o recurso em si—por exemplo, um objeto de diretório, arquivo ou pasta. Em seguida, há o objeto da ACL (Lista de Controle de Acesso), que está anexado ao recurso. A ACL consiste em uma ou mais Entradas de Controle de Acesso, ou objetos ACE. Uma ACE essencialmente vincula uma entidade de segurança (um usuário ou grupo, que é outro objeto) a uma permissão (como de Leitura ou Controle Total) e a um status Conceder ou Negar. Há não menos do que cinco objetos: o recurso, a ACL, uma ACE, uma entidade e uma permissão.

As permissões são ainda mais complicadas pelo fato de que todo tipo de recurso tem diferentes tipos de permissão. Objetos de diretório, por exemplo, têm permissões complexas governando o acesso a atributos de objeto individuais. Permissões de arquivo são relativamente pouco complicadas, em comparação.

E, tecnicamente, tudo isso é duplicado em se tratando de auditorias. Cada recurso tem, na verdade, duas ACLs. Em primeiro lugar, há a DACL (Lista de Controle de Acesso Condicional), que governa o acesso ao recurso. Em segundo lugar, há a SACL (Lista de Controle de Acesso de Segurança), que controla a auditoria do recurso. Tentar trabalhar com essas permissões significa lidar com uma pilha de objetos de programação razoavelmente complicados e há um limite para o que um shell como o Windows PowerShell pode fazer para simplificar isso para você.

Limitado pelo .NET Framework

Ainda quer mais?

Para obter mais recursos do Windows PowerShell, incluindo uma biblioteca pesquisável de cmdlets, e para conectar-se com Don Jones e outros especialistas em Windows PowerShell, visite www.PowerShellCommunity.org.

A natureza do Windows PowerShell torna as coisas um pouco mais complicadas. Por ser baseado no Microsoft® .NET Framework, o Windows PowerShell usa as classes subjacentes do .NET Framework para representar e trabalhar com permissões. Essas classes subjacentes do .NET Framework foram criadas para fornecer aos desenvolvedores de software um controle granular e preciso sobre as permissões. É claro, "granular e preciso" significa muita informação e muitas vezes é traduzido como "muito complicado".

Além disso, o .NET Framework não fornece classes que representem as permissões de todos os tipos de recursos do Windows. Por exemplo, enquanto o .NET Framework fornece classes que permitem a manipulação da segurança dos arquivos, ele não fornece classes que permitem o trabalho com a segurança em pastas compartilhadas. O resultado é que o Windows PowerShell não pode manipular permissões em todos os tipos de recursos do Windows. Simplificando, o Windows PowerShell é limitado às capacidades oferecidas pelo .NET Framework.

Permissões no Shell

O gerenciamento de permissões no Windows PowerShell é derivado de dois cmdlets: Get-ACL e Set-ACL. Como esperado, Get-ACL recupera a ACL de um recurso. É possível modificar a ACL para atender às suas necessidades e usar Set-ACL para gravá-la novamente no recurso. Esses dois cmdlets são genéricos e recorrem ao sistema do Windows PowerShell de fornecedores PSDrive. Portanto, esses dois cmdlets ACL poderiam, teoricamente, trabalhar com qualquer tipo de recurso, desde que haja um fornecedor PSDrive capaz de compreender um tipo de recurso específico e de modificar as suas permissões. Os fornecedores PSDrive FileSystem e Registry, que estão incluídos no Windows PowerShell, oferecem suporte ao gerenciamento de permissões por meio de dois cmdlets ACL. (Outros fornecedores PSDrive podem não oferecer esse suporte).

O script de exemplo mostrado na Figura 1 permite especificar um diretório inicial, uma entidade de segurança e uma permissão. O script aplica a permissão especificada para aquela entidade para todos os arquivos e pastas dentro do diretório especificado. O script pesquisa de forma recursiva os subdiretórios também.

Figure 1 Aplique uma permissão de uma entidade a arquivos e pastas em um diretório

#ChangeACL.ps1
$Right="FullControl"

#The possible values for Rights are 
# ListDirectory, ReadData, WriteData 
# CreateFiles, CreateDirectories, AppendData 
# ReadExtendedAttributes, WriteExtendedAttributes, Traverse
# ExecuteFile, DeleteSubdirectoriesAndFiles, ReadAttributes 
# WriteAttributes, Write, Delete 
# ReadPermissions, Read, ReadAndExecute 
# Modify, ChangePermissions, TakeOwnership
# Synchronize, FullControl

$StartingDir=Read-Host "What directory do you want to start at?"
$Principal=Read-Host "What security principal do you want to grant" `
"$Right to? `n Use format domain\username or domain\group"

#define a new access rule.
#note that the $rule line has been artificially broken for print purposes.
#it needs to be one line. the online version of the script is properly
#formatted.
$rule=new-object System.Security.AccessControl.FileSystemAccessRule
($Principal,$Right,"Allow")

foreach ($file in $(Get-ChildItem $StartingDir -recurse)) {
  $acl=get-acl $file.FullName
 
  #Add this access rule to the ACL
  $acl.SetAccessRule($rule)
  
  #Write the changes to the object
  set-acl $File.Fullname $acl
  }

A parte suculenta desse script é onde ele define uma nova regra de acesso na variável $rule. Para fazer isso, estou usando uma classe do .NET Framework “crua”, que é talvez a parte mais complicada do gerenciamento de permissões no Windows PowerShell. Em seguida, o script recupera a ACL de cada arquivo e pasta separadamente, usando Get-ACL, aplica a nova regra usando o método SetAccessRule da ACL e grava a ACL modificada de volta no recurso usando Set-ACL.

Na realidade, isso não é tão complicado, embora operações mais complexas como remover uma ACE de uma ACL envolvam mais. Em minha opinião, o que faz parecer complicado é o fato de haver tantas etapas envolvidas: obter a ACL, definir uma regra, modificar a ACL e gravar a ACL. Não é um comando único e limpo que faz tudo de uma vez. E como eu desejava modificar as ACLs em vários arquivos, tive de juntar tudo em um loop foreach, usando Get-ChildItem para acessar todos os arquivos e pastas.

Farei da maneira mais fácil

Cmdlet do mês: Get-QADUser

Esse cmdlet é obrigatório se você gerencia um Active Directory. Ele não é interno no Windows PowerShell, mas está disponível para download gratuito como parte do ActiveRoles Management Shell for Active Directory da Quest Software (www.quest.com/activeroles-server/arms.aspx).

Depois de instalar o snap-in, é possível usar o Get-QADUser para recuperar objetos de usuário do diretório. Claro, simplesmente executar o cmdlet retorna todos os seus usuários, o que não é exatamente útil para a maioria das tarefas administrativas. Mas o cmdlet permite a especificação de critérios de filtragem, que são aplicadas no controlador de domínio para que somente os usuários com os quais você estiver preocupados sejam realmente retornados ao Windows PowerShell. Essa é uma técnica muito mais rápida do que obter todos os usuários e, em seguida, filtrá-los com o cmdlet Where-Object. Por exemplo, Get-QADUser -l Redmond retornará somente os usuários cujo atributo "l" contenha "Redmond." (A propósito, o atributo "l" signifca localidade e é listado como cidade na GUI). É possível canalizar esses usuários para outros cmdlets para gerar um relatório em HTML, colocá-los em um grupo ou mesmo excluí-los.

Não acho que o meu exemplo seja complexo, mas sei que muitos administradores prefeririam uma maneira mais simples de trabalhar com permissões. Talvez eles desejem remover um grupo de usuários de um conjunto de pastas todos de uma vez mas não desejam escrever um script de várias etapas como o mostrado na Figura 1.

Felizmente, o Windows PowerShell oferece um meio simplificado de trabalhar com permissões e você provavelmente já o conhece.

O Windows PowerShell não faz você desistir das maneiras famosas de fazer as coisas. É possível usar ainda as ferramentas de linha de comando—como Dsacls.exe, Cacls.exe e Xcacls.exe—que foram desenvolvidas especificamente para fornecer uma maneira mais simples de trabalhar com vários tipos de permissões. Embora sua sintaxe seja completamente diferente da sintaxe padronizada usada pelos cmdlets do Windows PowerShell, esses utilitários de linha de comando não precisam mais ser usados em uma maneira ad hoc na linha de comando como eram usadas no antigo shell cmd.exe. E é possível usar o Windows PowerShell para automatizar esses utilitários.

Eu encontrei alguns caras—os chamarei de "puristas"—que insistem que usar um utilitário de linha de comando antigo dentro do Windows PowerShell é, de alguma forma, errado. Não entendo sua lógica. Sou a favor que o trabalho seja feito e se a maneira mais fácil for usar um utilitário de linha de comando de 10 anos, é o que farei. Não gastarei horas a mais tentando fazer algo de uma determinada maneira somente porque parece "mais pura". E a equipe do Microsoft Windows PowerShell tem uma atitude semelhante. Se uma ferramenta existente faz o trabalho, deixe o Windows PowerShell usar essa ferramenta dentro do shell. Para quê reinventar a roda?

A Figura 2 mostra um script curto—retirado do meu livro Windows PowerShell: TFM (SAPIEN Press, 2006)—que usa o Windows PowerShell para automatizar o Cacls.exe. Esse script é somente uma demonstração, o que significa que você precisará ajustá-lo se desejar torná-lo uma ferramenta de automação real. Mas ele mostra como um script do Windows PowerShell pode coletar informações e usá-las para iniciar o Cacls.exe, como se o Cacls.exe fosse um comando "nativo" do Windows PowerShell. (Embora esse script colete informações solicitando-as ao usuário, os parâmetros poderiam ser lidos de um arquivo ou banco de dados).

Figure 2 Automatize o Cacls.exe

#SetPermsWithCACLS.ps1
# CACLS rights are usually
# F = FullControl
# C = Change
# R = Readonly
# W = Write

$StartingDir=Read-Host "What directory do you want to start at?"
$Right=Read-Host "What CACLS right do you want to grant? Valid choices are F, C, R or W"
Switch ($Right) {
  "F" {$Null}
  "C" {$Null}
  "R" {$Null}
  "W" {$Null}
  default {
    Write-Host -foregroundcolor "Red" `
    `n $Right.ToUpper() " is an invalid choice. Please Try again."`n
    exit
  }
}

$Principal=Read-Host "What security principal do you want to grant?" `
"CACLS right"$Right.ToUpper()"to?" `n `
"Use format domain\username or domain\group"

$Verify=Read-Host `n "You are about to change permissions on all" `
"files starting at"$StartingDir.ToUpper() `n "for security"`
"principal"$Principal.ToUpper() `
"with new right of"$Right.ToUpper()"."`n `
"Do you want to continue? [Y,N]"

if ($Verify -eq "Y") {

 foreach ($file in $(Get-ChildItem $StartingDir -recurse)) {
  #display filename and old permissions
  write-Host -foregroundcolor Yellow $file.FullName
  #uncomment if you want to see old permissions
  #CACLS $file.FullName
  
  #ADD new permission with CACLS
  CACLS $file.FullName /E /P "${Principal}:${Right}" >$NULL
  
  #display new permissions
  Write-Host -foregroundcolor Green "New Permissions"
  CACLS $file.FullName
 }
}

Sucesso com as Permissões?

Ouvi argumentos que diziam que o Windows PowerShell deixa a desejar em se tratando de permissões porque não fornece um cmdlet nativo que ofereça gerenciamento de permissões simplificado e universal. Eu não concordo. Em primeiro lugar, esse argumento é, muitas vezes, dito por administradores com antecedentes fortes em UNIX e o fato é que o sistema de permissões do Windows é extremamente mais complicado do que o usado no UNIX. Ao expor esse sistema, o Windows PowerShell também será complicado. No entanto, esse não é um problema do Windows PowerShell.

Além disso, o Windows PowerShell permite o uso de ferramentas simplificadas na forma dos velhos e bons utilitários de linha de comando, como demonstrei aqui. É verdade, o .NET Framework precisa de alguma expansão para abordar mais profundamente o gerenciamento de permissões na plataforma Windows inteira. Mas no geral, o Windows PowerShell oferece a você os dois mundos: gerenciamento de permissões simplificados bem como acesso a ferramentas de gerenciamento granulares e precisas.

Don Jones é editor-colaborador da TechNet Magazine e co-autor de Windows PowerShell: TFM (SAPIEN Press, 2007). Ele é professor de Windows PowerShell (consulte www.ScriptingTraining.com) e pode ser contatado pelo site www.ScriptingAnswers.com.

© 2008 Microsoft Corporation e CMP Media, LLC. Todos os direitos reservados. A reprodução parcial ou completa sem autorização é proibida..