Protéger un objet des suppressions accidentelles avec PowerShell

Lorsque l’on utilise PowerShell pour créer des objets dans ActiveDirectory, il peut être intéressant dans le cas d’une OU ou d’un container d’appliquer le paramètres de Protection de l’objet des suppressions accidentelles, comme le fait si bien la case à cocher disponible dans la MMC.

 

Bon, une case à cocher c’est très bien, mais quand on viens de faire un joli script qui nous créé en une seule passe les 150 OU de notre organisation AD, quand viens le moment de cocher 150 cases il viens comme une envie de se pendre (surtout qu’avant d’atteindre la case à cocher il aura fallu malmener sérieusement le clic gauche de la souris -_-)

En réalité, derrière cette case à cocher se cache trois ACE très simples, l’octroi du refus pour le groupe Builtin « Tout le monde » sur l’objet en question:

Maintenant il ne me reste plus qu’à vous montrer comment appliquer des ACE sur un objet de l’AD avec un script PowerShell.

Je ne vais décrire ici que la partie qui nous intéresse, se connecter à un objet ActiveDirectory de type OU pour l’exemple (ca marche évidement avec n’importe quel objet).

Le principe est assez simple, on commence par se connecter à l’objet avec la classe DirectoryServices.DirectoryEntry, puis on crée des objets ACE avec la classe DirectoryServices.ActiveDirectoryAccessRule.

Cette classe attend plusieurs paramètre dont le SID de l’objet qui va bénéficier de l’ACE, dans notre cas le SID est S-1-1-0 (SID spécifique correspondant au groupe Builtin « Tout le monde »).

Il faut également spécifier les droits que l’on veux authoriser ou refuser avec la collection DirectoryServices.ActiveDirectoryRights.

Finalement on précise le type d’ACE (Allow ou Deny) et l’héritage (ici None ce qui correspond à l’objet lui-même), respectivement avec les collections System.AccessControl.AccessControlType et DirectoryServices.ActiveDirectorySecurityInheritance.

Ne reste plus qu’à ajouter les ACE à l’objet et à valider le tout avec un Commit.

# Connect to Object
$Object = New-Object System.DirectoryServices.DirectoryEntry("LDAP://OU=Test,DC=olympe,DC=demo")
# Add ACE to Deny Delete, DeleteChild and DeleteTree for Everyone (which is actually the rights to protected from accidental deletion)
$Trustee = New-Object Security.Principal.SecurityIdentifier("S-1-1-0") # S-1-1-0 is the SID for Everyone Built-In Group
$ACType = [Security.AccessControl.AccessControlType]::Deny
$Inheritance = [DirectoryServices.ActiveDirectorySecurityInheritance]::None
# Create and add ACE
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Trustee, [DirectoryServices.ActiveDirectoryRights]::Delete, $ACType, $Inheritance)
$Object.psbase.ObjectSecurity.AddAccessRule($ACE)
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Trustee, [DirectoryServices.ActiveDirectoryRights]::DeleteChild, $ACType, $Inheritance)
$Object.psbase.ObjectSecurity.AddAccessRule($ACE)
$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($Trustee, [DirectoryServices.ActiveDirectoryRights]::DeleteTree, $ACType, $Inheritance)
$Object.psbase.ObjectSecurity.AddAccessRule($ACE)
# Apply ACE
$Object.psbase.CommitChanges()

Si la case à cocher est disponible dans le clicodrome uniquement, en utilisant un script adapté on peut imaginer protéger n’importe quel objet que l’on crée ou veux modifier. Par exemple des groupes de sécurité utilisés pour la délégation, ou bien des listes de distribution, ou encore des comptes de services.

Bref, cela permet d’éviter bien des sueurs à nos admins de domaine ^^

 

Bonne lecture.

Joris