Imaginez : votre collaborateur le plus ancien, 20 ans de maison, part en retraite.
Son compte Active Directory a accumulé des droits au fil des années : accès à la Comptabilité, à des dossiers Juridiques sensibles, voire à des projets anciens.
Problème : ni lui, ni vous ne savez précisément à quoi il a accès. Résultat ? Vous êtes bloqués : impossible de fermer son compte proprement, et vous laissez tourner un identifiant inactif, qui reste une faille de sécurité potentielle.
Chez DYB, nous voyons ce scénario tous les mois : héritage de droits mal gérés, dossiers partagés en vrac, comptes laissés ouverts par peur de casser une application ou bloquer l’accès à des documents.
La réponse : l’AGDLP automatisé
La bonne pratique en sécurité Windows Server et Active Directory est le modèle AGDLP :
- Accounts (comptes utilisateurs)
- Global groups (par équipe ou métier)
- Domain Local (porteurs des droits NTFS)
- Permissions (appliquées sur les dossiers)
Ce modèle permet de garder une structure claire et facilement maintenable.
👉 Mais mis en place à la main, c’est long, fastidieux, et donc souvent bâclé.
L’automatisation par DYB
Nous avons conçu un script PowerShell qui applique automatiquement cette logique :
- Création des groupes GDL pour chaque projet ou dossier, en lecture (RO) et écriture (RW).
- Imbrication automatique des groupes existants dans le bon niveau de droits.
- Attribution simplifiée des permissions NTFS.
<#
.SYNOPSIS
Script DYB : création et imbrication automatique de groupes AGDLP pour sécurisation des accès projets.
.DESCRIPTION
- Parcourt deux OUs source (groupes existants de projets Clients et Internes).
- Crée automatiquement pour chaque groupe trouvé deux groupes Domain Local (GDL_{Nom}_RO et GDL_{Nom}_RW).
- Ajoute le groupe source comme membre du GDL_{Nom}_RW (pattern AGDLP).
- Permet une gestion claire et évolutive des droits NTFS.
Version : DYB 2025
#>
Import-Module ActiveDirectory
# ================== VARIABLES À ADAPTER ==================
# OUs SOURCE : là où se trouvent tes groupes "projets" existants
$OU_Source_Clients = "OU=Projets-Clients,OU=Groups,DC=dyb,DC=lan"
$OU_Source_Internes = "OU=Projets-Internes,OU=Groups,DC=dyb,DC=lan"
# OUs CIBLES : où créer les GDL_*_RO/RW correspondants
$OU_Target_Clients = "OU=ACL-Clients,OU=Security,DC=dyb,DC=lan"
$OU_Target_Internes = "OU=ACL-Internes,OU=Security,DC=dyb,DC=lan"
# =========================================================
# Sanitize sAMAccountName (<=20, obligatoire en AD)
function New-SafeSam {
param([Parameter(Mandatory)][string]$Name)
$base = ($Name -replace "[^0-9A-Za-z_-]", "_")
if ($base.Length -le 20) { return $base }
# hash court stable si trop long
$hash = [System.BitConverter]::ToString(
(New-Object System.Security.Cryptography.SHA1Managed).ComputeHash(
[System.Text.Encoding]::UTF8.GetBytes($base)
)
).Replace("-","").Substring(0,4).ToLower()
$keep = 20 - 5
return ($base.Substring(0,$keep) + "_" + $hash)
}
# Création des groupes GDL_{Nom}_RO et GDL_{Nom}_RW
function Ensure-GDLGroups {
param(
[Parameter(Mandatory)][string]$SourceOU,
[Parameter(Mandatory)][string]$TargetOU
)
$srcGroups = Get-ADGroup -SearchBase $SourceOU -LDAPFilter "(objectClass=group)" -SearchScope OneLevel `
-Properties name | Sort-Object Name
foreach ($g in $srcGroups) {
$projName = $g.Name
foreach ($right in @("RO","RW")) {
$cnName = "GDL_{0}_{1}" -f $projName, $right
$samName = New-SafeSam $cnName
$existing = Get-ADGroup -LDAPFilter "(cn=$cnName)" -SearchBase $TargetOU -ErrorAction SilentlyContinue
if ($existing) {
Write-Host "[SKIP] $cnName existe déjà dans $TargetOU"
continue
}
New-ADGroup -Name $cnName `
-SamAccountName $samName `
-GroupScope DomainLocal -GroupCategory Security `
-Path $TargetOU `
-Description ("ACL {0} ({1})" -f $projName,$right)
Write-Host "[OK] Créé : $cnName (SAM:$samName)"
}
}
}
# Ajout du groupe source dans GDL_{Nom}_RW
function Add-Sources-To-RW {
param(
[Parameter(Mandatory)][string]$SourceOU,
[Parameter(Mandatory)][string]$TargetOU
)
$srcGroups = Get-ADGroup -SearchBase $SourceOU -LDAPFilter "(objectClass=group)" -SearchScope OneLevel `
-Properties name,distinguishedName | Sort-Object Name
foreach ($g in $srcGroups) {
$projName = $g.Name
$targetRW = "GDL_{0}_RW" -f $projName
$safe = $targetRW.Replace("'", "''")
$rwGroup = Get-ADGroup -Filter "Name -eq '$safe'" -SearchBase $TargetOU -ErrorAction SilentlyContinue
if (-not $rwGroup) {
Write-Warning "Cible introuvable: $targetRW (skip)."
continue
}
try {
Add-ADGroupMember -Identity $rwGroup.DistinguishedName -Members $g.DistinguishedName -ErrorAction Stop
Write-Host "[OK] $($g.Name) -> membre de $($rwGroup.Name)"
} catch {
if ($_.Exception.Message -match "already a member") {
Write-Host "[SKIP] $($g.Name) déjà membre de $($rwGroup.Name)"
} else {
Write-Warning "Échec ajout membre: $($g.Name) -> $($rwGroup.Name) : $($_.Exception.Message)"
}
}
}
}
# ==== LANCEMENT ====
Ensure-GDLGroups -SourceOU $OU_Source_Clients -TargetOU $OU_Target_Clients
Ensure-GDLGroups -SourceOU $OU_Source_Internes -TargetOU $OU_Target_Internes
Add-Sources-To-RW -SourceOU $OU_Source_Clients -TargetOU $OU_Target_Clients
Add-Sources-To-RW -SourceOU $OU_Source_Internes -TargetOU $OU_Target_Internes
Write-Host "=== Terminé : Groupes GDL créés + imbrication RW réalisée ==="
Exemple concret : vos dossiers clients
Chaque client dispose de son dossier dédié avec des données sensibles : contrats, factures, documents internes.
Notre script génère automatiquement deux groupes :
GDL_NomDuClient_RO
pour la consultationGDL_NomDuClient_RW
pour l’édition
Résultat : une gestion granulaire et sécurisée des accès, sans pertes de temps ni erreurs humaines.
Conclusion
Avec l’AGDLP automatisé, vous gardez le contrôle sur vos partages de fichiers :
- Droits clairs et audités
- Accès facilement révoqués
- Risques réduits en cas de départ ou de mobilité interne
Chez DYB, nous accompagnons les entreprises dans la mise en place de ces bonnes pratiques, avec un objectif simple : sécuriser vos données tout en vous simplifiant l’administration.