Windows PowerShellAutorizzazioni della shell

Don Jones

Scarica il codice per questo articolo: PowerShell2008_02.exe (151KB)

Nelle discussioni su Windows PowerShell mi vengono spesso poste domande relative alle autorizzazioni, in particolare se e come la shell consente di automatizzare le modifiche alle autorizzazioni. Le domande più comuni sono probabilmente quelle relative alle autorizzazioni per i file, anche se è piuttosto frequente anche la richiesta di delucidazioni in merito alle autorizzazioni per le directory e il Registro di sistema. A proposito delle autorizzazioni e di quasi

tutte le interfacce di script o della riga di comando, compresi Windows PowerShellTM e VBScript, dobbiamo dire che abbiamo notizie buone e notizie cattive.

Le notizie cattive sono che le autorizzazioni Windows® sono per natura piuttosto complesse e Windows PowerShell non è in grado di fornire alcuna soluzione adeguata per aggirare questo problema. Il problema deriva dal fatto che in un sistema operativo Windows, quando si tratta di autorizzazioni, è necessario avere a che fare con molteplici oggetti, indipendentemente da se si stia esaminando il file system, Active Directory®, il Registro di sistema o altro.

Innanzitutto, occorre prendere in considerazione la risorsa stessa, ad esempio un oggetto directory, un file o una cartella. Successivamente è necessario tener conto dell'oggetto elenco di controllo di accesso (ACL), che è associato alla risorsa. L'ACL è composto da una o più voci di controllo di accesso o oggetti ACE. Una voce ACE essenzialmente consente di correlare un'entità di protezione (un utente o un gruppo, ovvero un altro oggetto) a un'autorizzazione, ad esempio Lettura o Controllo completo, e a uno stato di concessione o negazione. Occorre pertanto prendere in considerazione non meno di cinque oggetti: la risorsa, l'ACL, una voce ACE, un'entità di protezione e un'autorizzazione.

L'utilizzo delle autorizzazioni risulta ulteriormente complicato dal fatto che ogni tipo di risorsa dispone di diversi tipi di autorizzazione. Gli oggetti directory, ad esempio, dispongono di autorizzazioni complesse che regolano l'accesso ai singoli attributi degli oggetti. Le autorizzazioni per i file sono in confronto relativamente semplici.

Dal punto di vista tecnico, le difficoltà raddoppiano al momento di eseguire il controllo. Ogni risorsa dispone in effetti di due ACL: l'ACL discrezionale (DACL), che regola l'accesso alla risorsa e l'ACL di protezione (SACL), che monitora il controllo sulla risorsa. L'utilizzo di queste autorizzazioni implica la necessità di procedere tra un'ampia gamma di oggetti di programmazioni piuttosto complessi e solo una shell come Windows PowerShell è in grado di semplificare questa attività.

Limitazioni di .NET Framework

Risorse aggiuntive

Per ulteriori risorse su Windows PowerShell, compresa una libreria di cmdlet su cui è possibile eseguire ricerche, e per informazioni su come contattare Don Jones e altri esperti di Windows PowerShell, visitare il sito www.PowerShellCommunity.org.

La natura di Windows PowerShell rende le cose un po' più complesse. Poiché è basato su Microsoft® .NET Framework, per la rappresentazione e l'utilizzo delle autorizzazioni Windows PowerShell utilizza le classi sottostanti di .NET Framework. Le classi sottostanti di .NET Framework sono progettate per fornire agli sviluppatori software un controllo granulare e preciso sulle autorizzazioni. Ovviamente, un controllo "granulare e preciso" implica la necessità di esaminare una grande quantità di informazioni, che si traduce spesso in una maggiore complessità.

Inoltre, .NET Framework non fornisce classi che rappresentano tutte le autorizzazioni in ogni tipo di risorsa di Windows. Ad esempio, sebbene .NET Framework fornisca classi che consentono di manipolare la protezione dei file, non fornisce classi che consentono di utilizzare la protezione sulle cartelle condivise. Il risultato è che Windows PowerShell non è in grado di manipolare le autorizzazioni per ogni tipo di risorsa di Windows. In parole semplici, Windows PowerShell è limitato alle funzionalità esposte da .NET Framework.

Autorizzazioni all'interno della shell

La gestione delle autorizzazioni in Windows PowerShell viene derivata da due cmdlet: Get-ACL e Set-ACL. Come è facile immaginare, Get-ACL consente di recuperare l'ACL da una risorsa. È possibile modificare l'ACL in base alle proprie esigenze e utilizzare Set-ACL per scrivere l'ACL nuovamente nella risorsa. Entrambi questi cmdlet sono generici e si basano sul sistema di provider PSDrive di Windows PowerShell. Di conseguenza, questi due cmdlet ACL potrebbero in teoria funzionare con qualsiasi tipo di risorsa, purché sia disponibile un provider PSDrive in grado di riconoscere un determinato tipo di risorsa e di modificare le autorizzazione per il tipo di risorsa in questione. I provider PSDrive FileSystem e Registry, che vengono forniti con Windows PowerShell, supportano la gestione delle autorizzazioni tramite i due cmdlet ACL. Gli altri provider PSDrive potrebbero non fornire questo supporto.

Lo script di esempio illustrato nella Figura 1 consente di specificare una directory di partenza, un'entità di protezione e un'autorizzazione. Lo script applica quindi l'autorizzazione specificata per tale entità a tutti i file e le cartelle all'interno della directory specificata. Lo script applica l'autorizzazione anche alle sottodirectory.

Figure 1 Applicazione di un'autorizzazione per un'entità a file e cartelle in una directory

#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
  }

Lo scopo principale di questo script consiste nel definire una nuova regola di accesso nella variabile $rule. A tal fine, verrà utilizzata una classe .NET Framework "non elaborata", che rappresenta probabilmente la parte più complessa della gestione delle autorizzazioni in Windows PowerShell. Lo script recupera quindi l'ACL da ciascun file e cartella utilizzando Get-ACL, applica la nuova regola utilizzando il metodo SetAccessRule dell'ACL e scrive l'ACL modificato di nuovo nella risorsa mediante Set-ACL.

In realtà, questa procedura non è eccessivamente complessa anche se alcune operazioni, come la rimozione di una voce ACE da un ACL, sono molto più complesse. A mio parere, ciò che fa apparire questo processo complicato è il fatto che prevede un elevato numero di passaggi: ottenere l'ACL, definire una regola, modificare l'ACL e scrivere l'ACL. Non è disponibile un unico semplice comando che consenta di eseguire tutte queste operazioni in una sola volta. E poiché si intendeva modificare gli ACL in più file, si è reso necessario inserire il tutto in un ciclo foreach utilizzando Get-ChildItem per accedere a tutti i file e le cartelle.

Il metodo più semplice

Cmdlet del mese: Get-QADUser

Questo cmdlet è essenziale se si gestisce Active Directory. Non è integrato in Windows PowerShell, ma è disponibile come download gratuito come parte di Quest Software ActiveRoles Management Shell per Active Directory (www.quest.com/activeroles-server/arms.aspx).

Una volta installato lo snap-in, è possibile utilizzare Get-QADUser per recuperare gli oggetti utente dalla directory. Ovviamente, la semplice esecuzione del cmdlet determina la restituzione di tutti gli utenti, un risultato non particolarmente utile per la maggior parte delle attività amministrative. Tuttavia, il cmdlet consente di specificare criteri di filtro, che vengono applicati a livello di controller di dominio in modo che vengano restituiti a Windows PowerShell solo gli utenti a cui si è interessati. Questa è una tecnica molto più rapida rispetto al metodo precedente che prevedeva il recupero e il filtraggio di tutti gli utenti mediante il cmdlet Where-Object. Get-QADUser -l Redmond, ad esempio, consente solo di restituire gli utenti il cui attributo "l" contiene "Redmond" (l'attributo "l" sta per località e viene elencato come città nell'interfaccia utente grafica). È possibile inviare tali utenti ad altri cmdlet in modo da generare un report HTML, inserirli in un gruppo o persino eliminarli.

Ritengo che l'esempio illustrato in questo articolo non sia complesso, ma so che molti amministratori preferirebbero un metodo più semplice per l'utilizzo delle autorizzazioni. È probabile che gli amministratori desiderino rimuovere contemporaneamente uno specifico gruppo di utenti da un insieme di cartelle ma che non desiderino scrivere uno script costituito da più passaggi come quello riportato nella Figura 1.

Fortunatamente, Windows PowerShell offre un metodo semplificato per l'utilizzo delle autorizzazioni con cui probabilmente gli amministratori hanno già una certa familiarità.

L'utilizzo di Windows PowerShell non implica la necessità di rinunciare a metodi di comprovata efficienza. È possibile continuare a utilizzare gli strumenti della riga di comando, come Dsacls.exe, Cacls.exe e Xcacls.exe, progettati specificamente per fornire un metodo più semplice per l'utilizzo di diversi tipi di autorizzazioni. Anche se la sintassi di tali strumenti è completamente differente dalla sintassi standardizzata utilizzata dai cmdlet di Windows PowerShell, non è più necessario l'utilizzo ad hoc nella riga di comando di queste utilità della riga di comando, così come venivano utilizzate nella shell cmd.exe precedente. Inoltre, con Windows PowerShell è possibile automatizzare queste utilità.

Mi è talvolta capitato di imbattermi in persone, che definisco "puristi", che affermano che è sbagliato utilizzare un'utilità della riga di comando obsoleta all'interno di Windows PowerShell. In effetti, non riesco a seguire la loro logica. Se riesco a ottenere i risultati desiderati e se il metodo più semplice per ottenerli è utilizzare un'utilità della riga di comando "vecchia di dieci anni", non c'è nulla da biasimare. Non sprecherò tempo prezioso a provare di eseguire un'operazione in un certo modo solo perché tale metodo sembra "più puro". Il team di Microsoft Windows PowerShell ha un atteggiamento simile. Se uno strumento esistente consente di eseguire correttamente l'operazione desiderata, Windows PowerShell consentirà di utilizzare tale strumento all'interno della shell. Perché partire da zero?

Nella Figura 2 viene illustrato un breve script, tratto dal mio libro Windows PowerShell: TFM (SAPIEN Press, 2006), che prevede l'utilizzo di Windows PowerShell per automatizzare Cacls.exe. Questo script è una semplice dimostrazione e pertanto sarà necessario modificarlo se si desidera trasformarlo in un vero e proprio strumento di automazione. Dimostra tuttavia come uno script di Windows PowerShell sia in grado di raccogliere informazioni e utilizzarle per avviare l'utilità Cacls.exe, come se Cacls.exe fosse un comando Windows PowerShell "nativo". Sebbene questo script sia in grado di raccogliere le informazioni richiedendole all'utente, i parametri possono essere anche letti da un file o un database.

Figure 2 Automazione di 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
 }
}

Successo con le autorizzazioni?

Alcuni sostengono che Windows PowerShell non fornisce risultati ottimali in termini di gestione delle autorizzazioni in quanto non è in grado di fornire un cmdlet nativo che offra una gestione semplificata e universale delle autorizzazioni. Non sono affatto d'accordo. Primo, questa argomentazione viene spesso avanzata da amministratori che hanno un forte background in ambiente UNIX e occorre tenere presente che il sistema di autorizzazioni di Windows è molto più complesso di quello utilizzato in UNIX. Quando si espone tale sistema, anche l'utilizzo di Windows PowerShell diventa complesso. Tuttavia, questo non è un problema specifico di Windows PowerShell.

Inoltre, Windows PowerShell consente di utilizzare strumenti semplificati sotto forma di utilità della riga di comando obsolete ma valide, come è stato dimostrato in questo articolo. È vero che si rende necessario espandere ulteriormente .NET Framework per coprire in modo più esaustivo la gestione delle autorizzazioni sull'intera piattaforma Windows. Tuttavia, nel complesso, Windows PowerShell offre entrambi gli approcci: gestione semplificata delle autorizzazioni e accesso a strumenti di gestione granulari e precisi.

Don Jones collabora con TechNet Magazine come redattore ed è coautore del libro Windows PowerShell: TFM (SAPIEN Press, 2007). È docente di corsi su Windows PowerShell (www.ScriptingTraining.com) ed è possibile contattarlo dal sito Web www.ScriptingAnswers.com.

© 2008 Microsoft Corporation e CMP Media, LLC. Tutti i diritti riservati. È vietata la riproduzione completa o parziale senza autorizzazione.