Affichage des articles dont le libellé est Ace. Afficher tous les articles
Affichage des articles dont le libellé est Ace. Afficher tous les articles

mercredi 11 décembre 2013

Listes d'accès (2/2).

Dans cette partie je vous propose un scripte complet qui permet de donner des droits sur un dossier et ses sous-dossiers. Ce programme réalise les actions suivantes.

Sur le Dossier :
- Le groupe Administrateurs prend le rôle de propriétaire.
- Donne le droit FullControl au groupe Administrateurs.
- Désactive l'héritage et supprime les droits (sauf "Administrateurs").
- Donne les droits du tableau "$global:droits" sur le dossier.

Sur les sous-dossier et fichiers :
- Le groupe Administrateurs prend le rôle de propriétaire.
- Réactive l'héritage (s'il n'est pas activé).
- Supprime les droits non-hérité du parent.

Usage :
Dans la variable "$dossier" entrez le chemin du dossier à modifier.
Dans le tableau "$global:droits" ajouté vos droits en suivant les exemples.

Je vous conseil de ne pas supprimer les lignes suivantes :
$global:droits  =  @()            #Initialisation du tableau (indispensable).
$global:droits += ,@("BUILTIN\Administrateurs","FullControl")
$global:droits += ,@("AUTORITE NT\SYSTEM","FullControl")


 
###################################################
#      Réinitialiser les droits d'un dossier
#       et de ses sous-dossiers et fichiers
###################################################

#Dossier à traiter.
$dossier = "C:\dossier1"

#Liste des groupes/utilisateurs et des droits.
#ReadAndExecute, Modify, FullControl.
$global:droits  =  @()   #Initialisation du tableau.
$global:droits += ,@("BUILTIN\Administrateurs","FullControl")
$global:droits += ,@("AUTORITE NT\SYSTEM","FullControl")
$global:droits += ,@("Utilisateurs","ReadAndExecute")
$global:droits += ,@("Jumbor12","Modify")

###################################################
#                    Fonctions
###################################################

### Définit le propriétaire d'un dossier.
function rd_owner([string] $roDossier,[string] $roGroupe)
 {
   #Je récupère les informations de mon dossier.
   $gdossier = Get-Item $roDossier
   #Je récupère la liste d'accès de mon dossier.
   $acl = $gdossier.GetAccessControl()
   #Je crée un objet $groupe.
   $groupe = New-Object System.Security.Principal.NTAccount($roGroupe)
   #Je modifie mon Acl.
   $acl.SetOwner($groupe)
   #Et j'applique l'Acl modifiée sur mon dossier.
   $gdossier.SetAccessControl($acl)
 }

### Initialise les droits sur le dossier racine.
function rd_racine([string] $rrDossier)
 {
   #Je réinitialise le propriétaire du dossier.
   rd_owner $rrDossier "BUILTIN\Administrateurs"

   #J'ajoute le groupe administrateurs à l'acl du dossier.
   rd_droit $rrDossier "BUILTIN\Administrateurs" "FullControl"

   #Je désactive l'héritage sur le dossier.
   $acl = get-acl -path $rrDossier             #Lecture de l'Acl.
   $acl.SetAccessRuleProtection($true,$true)   #Désactive l'héritage.
   Set-Acl -Path $rrDossier -AclObject $acl    #Mise à jour du dossier.

   #Puis je supprime les droits (sauf "Administrateurs").
   $acl = get-acl -path $rrDossier
   Foreach ($ace in $acl.Access)
     {
       #Lecture du droit de l'utilisateur.
       $groupe = [string] $ace.IdentityReference
       $droit = [string] $ace.FileSystemRights
       $type = [string] $ace.AccessControlType
       $heriter = $ace.IsInherited
       $IFlag = $ace.InheritanceFlags
       $PFlag = $ace.PropagationFlags 

       #Suppression des droits et de l'utilisateur.
       if ($groupe -ne "BUILTIN\Administrateurs")
         {
           $aco = new-object Security.AccessControl.FileSystemAccessRule($groupe,$droit,$IFlag,$PFlag,$type)
           $acl.RemoveAccessRuleAll($aco)
         }
     }

   #Mise à jour des droits sur le dossier.
   Set-Acl -Path $rrDossier -AclObject $acl
 }

### Réinitialise l'héritage sur les sous-dossiers. Les sous-dossiers
### et fichiers prendrons les mêmes droits que notre dossier.
function rd_heritage([string] $rhDossier)
 {
   #Je réinitialise le propriétaire du dossier.
   rd_owner $rhDossier "BUILTIN\Administrateurs"

   #J'active l'héritage sur le dossier.
   $acl = get-acl -path $rhDossier               #Lecture Acl.
   $acl.SetAccessRuleProtection($false,$false)   #Active l'héritage.
   Set-Acl -Path $rhDossier -AclObject $acl      #Mise à jour dossier.

   #Puis je supprime les droits non-hérité.
   $acl = get-acl -path $rhDossier
   Foreach ($ace in $acl.Access)
     {
       #Lecture du droit de l'utilisateur.
       $groupe = [string] $ace.IdentityReference
       $droit = [string] $ace.FileSystemRights
       $type = [string] $ace.AccessControlType
       $heritage = $ace.IsInherited
       $IFlag = $ace.InheritanceFlags
       $PFlag = $ace.PropagationFlags 
   
       #Suppression des droits non-hérité du parent.
       if (!$heritage)
         {
           $test = Get-Item $rhDossier
           if ($test.gettype().Name -eq "FileInfo")
             {
               $aco = new-object Security.AccessControl.FileSystemAccessRule($groupe,$droit,,,$type)
             }
           else
             {
               $aco = new-object Security.AccessControl.FileSystemAccessRule($groupe,$droit,$IFlag,$PFlag,$type)
             }
           $acl.RemoveAccessRuleAll($aco)
         }
     }

   #Mise à jour des droits sur le dossier.
   Set-Acl -Path $rhDossier -AclObject $acl
 }

### Défini les droits sur le dossier.
function rd_droit([string] $rdDossier,[string] $rdgroupe, [string] $rddroit)
 {
   #InheritOnly, None, NoPropagateInherit.
   $PFlag = [System.Security.AccessControl.PropagationFlags]::None

   #ContainerInherit, ObjectInherit, None.
   $IFlag = ([System.Security.AccessControl.InheritanceFlags]::ContainerInherit) -bor ([System.Security.AccessControl.InheritanceFlags]::ObjectInherit)

   #Je prepare le droit à positionner.
   $aco = new-object Security.AccessControl.FileSystemAccessRule($rdgroupe,$rddroit,$IFlag,$PFlag,"Allow")

   #Et je l'ajoute au dossier racine.
   $acl = get-acl -path $rdDossier            #Lecture de l'Acl.
   $acl.AddAccessRule($aco)                   #Mise à jour Acl.
   Set-Acl -Path $rdDossier -AclObject $acl   #Mise à jour du dossier.
 }

### Programme principale.
function rd_main([string] $rmDossier)
 {
   #J'initialise le dossier racine (owner/droit/héritage).
   rd_racine $rmDossier

   #Je donne les droits sur le dossier racine.
   foreach($droit in $global:droits)
    {
      rd_droit $rmDossier $droit[0] $droit[1]
    }

   #Je réinitialise l'héritage sur tout sous-dossiers afin
   #d'être sur que tout les sous-dossiers/fichiers prennent
   #les mêmes droits que notre dossier.
   Get-ChildItem $rmDossier -recurse -Force | foreach { rd_heritage($_.FullName) }
 }

###################################################
#                      Mains
###################################################

#Lancement du programme principale.
rd_main $dossier

#Fin.

Listes d'accès (1/2).

Les  listes d'accès (Acl) permettent de limiter l'accès à un dossier à une ou plusieurs personnes, et de définir pour chacun d'elles des droits spécifiques (lecture, écriture ...).

Dans cette première partie, Je vais vous monter différents exemples de scripts afin de réaliser les opérations suivantes sur un fichier ou un dossier :
- Lister les droits d'un fichier ou d'un dossier,
- Ajouter ou supprimer des droits à une personne, 
- Activer ou désactiver l'héritage sur un dossier,
- Modifier le propriétaire d'un fichier ou d'un dossier.

Commençons par lister les droits d'un fichier/dossier.

 
#Lister des droits d'un fichier ou dossier.
$dossier = "C:\dossier1"

#Je récupère la liste des droits sur le dossier.
$acl = get-acl -path $dossier

#Puis pour chaque utilisateurs présent dans la liste j'affiche ses droits d'accès.
ForEach ($ace in $acl.Access)
 {
   Write-Host $ace.IdentityReference "-" $ace.FileSystemRights "-" $ace.AccessControlType "-" $ace.IsInherited
 }

#Fin

Voici quelques explications complémentaires :
$ace.IdentityReference = utilisateur ou groupe.
$ace.FileSystemRights = droits (lecture, modification ...).
$ace.AccessControlType = permission ou interdiction du droit (allow or deny).
$ace.IsInherited = droit hérité du dossier parent ou non (true or false).

Ajoutons l'utilisateur "Jumbor12" avec le droit de modifier sur notre "dossier1".

 
#Ajouter un utilisateur/groupe sur un fichier/dossier.

#Dossier ou fichier à modifier.
$dossier = "C:\dossier1"

#Groupe ou utilisateur. Exemple : $groupe = "DOMAIN\GROUPE".
$groupe = "Jumbor12"

#Droits à ajouter
#$droit = "FullControl"     #Contrôle totale.
$droit = "Modify"           #Modifier.
#$droit = "ReadAndExecute"  #Lecture.

#Propagation (laissez les valeur par défaut).
#None, InheritOnly, NoPropagateInherit.
$PFlag = [System.Security.AccessControl.PropagationFlags]::None

#Héritage (laissez les valeur par défaut).
#None, ContainerInherit, ObjectInherit.
$IFlag = ([System.Security.AccessControl.InheritanceFlags]::ContainerInherit) -bor ([System.Security.AccessControl.InheritanceFlags]::ObjectInherit)

#Je construit un objet de contrôle d'accès (Aco).
$test = Get-Item $dossier
if ($test.gettype().Name -eq "FileInfo")
  {
    #Les fichiers ne supportent pas les options IFlag et PFlag.
    #Il faut donc les retirer.
    $aco = new-object Security.AccessControl.FileSystemAccessRule($groupe, $droit, , , "Allow")
  }
else
  {
    #Les dossiers par contre utilisent les options IFlag et PFlag.
    $aco = new-object Security.AccessControl.FileSystemAccessRule($groupe, $droit, $IFlag, $PFlag, "Allow")
  }

#Je récupère la liste d'accès de mon dossier.
$acl = get-acl -path $dossier

#J'ajoute mon Aco à ma liste d'accès.
$acl.AddAccessRule($aco)             #Ajoute un utilisateur + droit.
#$acl.RemoveAccessRule($aco)         #Supprime un droit uniquement.
#$acl.RemoveAccessRuleAll($aco)      #Supprime un utilisateur et tout ses droits.

#J'applique ma liste d'accès modifié à mon fichier/dossier.
Set-Acl -Path $dossier -AclObject $acl

#Fin

Pour supprimer un droit sur un fichier/dossier je remplace simplement dans mon script la ligne "$acl.AddAccessRule($aco)" par :

$acl.RemoveAccessRule($aco)

Mais si ceci supprime bien un droits, il ne supprime pas pour autant l'utilisateur/groupe lui même. Pour supprimer un utilisateur/groupe et tout ses droits il faut utiliser la ligne suivante :

$acl.RemoveAccessRuleAll($aco)

Maintenant que vous savez gérer les droits, il est temps de se pencher sur le problème de l'héritage. Par défaut, quand vous créez un nouveau dossier, il hérite automatiquement des droits de son parent. Dans certain cas ça nous arrange, et d'autres pas. Je vais donc vous montrer comment activer ou désactiver l'héritage d'un fichier/dossier.  

 
#Réactiver l'héritage.

#Dossier ou fichier à modifier.
$dossier = "C:\dossier1"

#Je récupère la liste d'accès de mon dossier.
$acl = get-acl -path $dossier

#Je active l'option héritage dans mon Acl.
#$acl.SetAccessRuleProtection($true,$true)     #Désactive l'héritage.
$acl.SetAccessRuleProtection($false,$false)    #Active l'héritage.

#J'applique mon Acl modifiée sur mon dossier.
Set-Acl -Path $dossier -AclObject $acl

#Puis je supprime les droits non-hérité.
#Je récupère la liste d'accès de mon dossier.
$acl = get-acl -path $dossier
#Pour chaque accès,
ForEach ($ace in $acl.Access)
 {
   $groupe = [string] $ace.IdentityReference
   $droit = [string] $ace.FileSystemRights
   $Type = [string] $ace.AccessControlType
   $Heritage = $ace.IsInherited
   $IFlag = $ace.InheritanceFlags
   $PFlag = $ace.PropagationFlags

   #Je vérifie si c'est un droit non-hérité.
   if (!$Heritage)
     {
       #Je vérifie si c'est un fichier ou un dossier.
       $test = Get-Item $dossier
       if ($test.gettype().Name -eq "FileInfo")
         {
        $aco = New-Object Security.AccessControl.FileSystemAccessRule($groupe, $droit, , , $Type)
         }
       else
         {
        $aco = New-Object Security.AccessControl.FileSystemAccessRule($groupe, $droit, $IFlag, $PFlag, $Type)
          }
        #Et je supprime l'utilisateur/groupe.
        $acl.RemoveAccessRuleAll($aco)
      }
  }

#J'applique la liste d'accès modifié sur mon dossier.
Set-Acl -Path $dossier -AclObject $acl

#Fin

Cette article touche presque à ca fin. Il nous reste plus qu'a voir la prise de possession d'un fichier/dossier (setowner).

 
#Prendre possession d'un fichier/dossier.#Dossier ou fichier à modifier.
$dossier = "C:\dossier1"

#Je récupère les informations de mon dossier.
$gdossier = Get-Item $dossier

#Je récupère la liste d'accès de mon dossier.
$acl = $gdossier.GetAccessControl()

#Je crée un objet $groupe
$groupe = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrateurs")

#Je modifie mon Acl.
$acl.SetOwner($groupe)

#Et j'applique l'Acl modifiée sur mon dossier.
$gdossier.SetAccessControl($acl)

#Enfin j'affiche le nom du nouveau propriétaire.
Write-Host "Propriétaire : " $acl.Owner

#Fin.