Active Directory et l’attribut UserAccountControl
Sommaire
I. Présentation
Le schéma de l'Active Directory contient un grand nombre d'attributs qui permettent de stocker les informations propres à un objet (utilisateur, ordinateur, etc.). Certains sont faciles à interpréter, car ils contiennent une valeur texte unique, c'est le cas par exemple de l'attribut "sAMAccountName" pour l'identifiant de connexion, l'attribut "mobile" pour le numéro de téléphone, ou encore l'attribut "whenCreated" qui contient la date de création de l'objet. D'autres attributs sont plus complexes et contiennent une valeur plus compliquée à interpréter : c'est le cas de UserAccountControl qui est l'un des attributs les plus importants de l'annuaire Active Directory.
Dans cet article, nous allons découvrir ensemble l'attribut UserAccountControl de l'Active Directory afin de voir à quoi il sert et nous verrons comment fonctionne la valeur de cet attribut dans le but de la comprendre, de l'interpréter. En tant qu'administrateur système, si vous utilisez l'Active Directory, cela fait partie des choses à connaître.
II. L'attribut UserAccountControl
L'attribut UserAccountControl est indispensable au bon fonctionnement de l'Active Directory, car sa valeur va permettre d'indiquer l'état d'un compte, selon plusieurs critères :
- Le compte est-il actif, désactivé ou verrouillé ?
- L'utilisateur doit-il changer son mot de passe à la prochaine connexion ?
- L'utilisateur peut-il changer son mot de passe ?
- Etc...
Au sein de l'Active Directory, configurer ces différentes options, il faut regarder l'onglet "Compte" d'un objet utilisateur. Voici un exemple :
Ces différentes options n'ont pas chacune leur attribut dédié, mais un attribut commun : UserAccountControl. Par exemple, si l'on modifie le champ "Nom d'ouverture de session de l'utilisateur", on sait que l'on va modifier la valeur de l'attribut "UserPrincipalName". Par contre, si l'on coche l'option "Le mot de passe n'expire jamais" et "Le compte est désactivé" au sein des options de compte, cela va influencer directement la valeur de l'attribut UserAccountControl, et non pas deux attributs distincts.
Finalement, on peut dire que ces différentes options sont binaires, soit c'est coché, soit c'est décoché. Autrement dit, soit c'est vrai (true donc 1 en binaire), soit c'est faux (false donc 0 en binaire). Je vous parle de valeurs binaires, car l'attribut UserAccountControl utilise la méthode "bitmask", où chaque bit de la valeur de cet attribut va correspondre à une option.
Certains critères sont propres aux utilisateurs, d'autres aux ordinateurs. Voici une liste des propriétés disponibles et qui sont susceptible d'influencer la valeur de l'attribut UserAccountControl :
Indicateur de propriété | Valeur hexadécimale | Valeur en décimal |
---|---|---|
SCRIPT | 0x0001 | 1 |
ACCOUNTDISABLE | 0x0002 | 2 |
HOMEDIR_REQUIRED | 0x0008 | 8 |
LOCKOUT | 0x0010 | 16 |
PASSWD_NOTREQD | 0x0020 | 32 |
PASSWD_CANT_CHANGE | 0x0040 | 64 |
ENCRYPTED_TEXT_PWD_ALLOWED | 0x0080 | 128 |
TEMP_DUPLICATE_ACCOUNT | 0x0100 | 256 |
NORMAL_ACCOUNT | 0x0200 | 512 |
INTERDOMAIN_TRUST_ACCOUNT | 0x0800 | 2048 |
WORKSTATION_TRUST_ACCOUNT | 0x1000 | 4096 |
SERVER_TRUST_ACCOUNT | 0x2000 | 8192 |
DONT_EXPIRE_PASSWORD | 0x10000 | 65536 |
MNS_LOGON_ACCOUNT | 0x20000 | 131072 |
SMARTCARD_REQUIRED | 0x40000 | 262144 |
TRUSTED_FOR_DELEGATION | 0x80000 | 524288 |
NOT_DELEGATED | 0x100000 | 1048576 |
USE_DES_KEY_ONLY | 0x200000 | 2097152 |
DONT_REQ_PREAUTH | 0x400000 | 4194304 |
PASSWORD_EXPIRED | 0x800000 | 8388608 |
TRUSTED_TO_AUTH_FOR_DELEGATION | 0x1000000 | 16777216 |
PARTIAL_SECRETS_ACCOUNT | 0x04000000 | 67108864 |
Les informations du tableau ci-dessus sont issues de la documentation Microsoft.
Passons maintenant à la partie pratique afin de voir comment lire la valeur UserAccountControl et comment exploiter le tableau ci-dessus pour interpréter cette valeur.
III. Comprendre la valeur UserAccountControl
Que ce soit à partir de l'interface graphique ou de PowerShell, on peut consulter l'attribut UserAccountControl d'un objet. Prenons l'exemple d'un utilisateur nommé "florian" et présent dans mon Active Directory.
A partir de la console "Utilisateurs et ordinateurs Active Directory", il faut activer les fonctionnalités avancés pour accéder à l'éditeur d'attributs. Pour cela, il est nécessaire de cliquer sur le bouton "Affichage" dans le menu puis "Fonctionnalités avancées".
Dans les propriétés du compte, via l'onglet "Editeur d'attributs", je retrouve assez facilement l'attribut et sa valeur : 0x10202 en hexadécimal et 66050 en décimal.
D'accord, c'est bien, mais comment convertir cette valeur afin de l'interpréter ? Pour s'aider, on peut s'appuyer sur le tableau ci-dessus et faire un peu de calcul mental (même si l'on verra qu'il y a plus simple). Déjà, au niveau de l'interface graphique, on remarque quelques indications : ACCOUNTDISABLE, NORMAL_ACCOUNT, DONT_EXPIRE_PASSWD.
Si je regarde dans le tableau, j'obtiens les valeurs décimales suivantes :
- ACCOUNTDISABLE : 2
- NORMAL_ACCOUNT : 512
- DONT_EXPIRE_PASSWD : 65536
En additionnant ces trois valeurs, on remarque que : 2 + 512 + 65536 = 66050 ! Dans ce cas, la valeur UserAccountControl signifie que le compte est désactivé, que le mot de passe n'expire jamais et qu'il s'agit d'un utilisateur classique (correspond à un type de compte par défaut).
Autres exemples :
- Si un utilisateur est simplement désactivé, la valeur de UserAccountControl sera : ACCOUNTDISABLE (2) + NORMAL_ACCOUNT (512) = 514.
- Un contrôleur de domaine aura la valeur 0x8200 soit 532480 (SERVER_TRUST_ACCOUNT + TRUSTED_FOR_DELEGATION)
- Un serveur ou un poste de travail membre du domaine aura la valeur 0x1000 soit 4096 (WORKSTATION_TRUST_ACCOUNT)
IV. UserAccountControl et PowerShell
Il est temps de passer à la vitesse supérieure et de voir comment exploiter l'attribut UserAccountControl avec PowerShell.
A. Lire l'attribut UserAccountControl avec PowerShell
Commençons par quelque chose de simple : récupérer la valeur UserAccountControl d'un utilisateur. Avec le cmdlet "Get-ADUser", il suffit de sélectionner la propriété UserAccountControl. Voici un exemple pour l'utilisateur "florian" :
Get-ADUser florian -Properties UserAccountControl | Select Name,UserAccountControl
On obtient bien la même valeur qu'avec l'interface graphique : tout va bien !
B. PowerShell et les filtres LDAP
La commande Get-ADUser de PowerShell contient un paramètre nommé "-LDAPFilter" qui permet de créer son propre filtre LDAP pour rechercher les utilisateurs dans l'AD. On peut utiliser ce paramètre pour rechercher tous les utilisateurs désactivés dans l'AD car on sait que, dans ce cas, UserAccountControl est égal à 514.
Ce qui donne :
Get-ADUser -Properties UserAccountControl -LDAPFilter "(useraccountcontrol=514)" | ft Name
Cette méthode fonctionne, mais le problème c'est que UserAccountControl peut avoir une valeur plus élevée s'il y a d'autres options activées, comme nous l'avons vu précédemment. Conséquence, le résultat ne sera pas forcément fiable (même si certaines combinaisons sont impossibles).
Afin d'identifier les comptes où le mot de passe est vide, on peut s'appuyer sur le flag "PASSWD_NOTREQD" correspondant à la valeur 32. Si l'on fait 512 + 32 = 544. Notre recherchera sera :
Get-ADUser -Properties UserAccountControl -LDAPFilter "(useraccountcontrol=544)" | ft Name
C. Convertir la valeur UserAccountControl avec PowerShell
Avec PowerShell, on peut convertir la valeur décimale de l'attribut UserAccountControl afin qu'elle soit plus compréhensible. J'ai récupéré un bout de code sur Reddit qui le fait très bien et que l'on peut adapter très facilement pour cibler toute ou partie l'Active Directory. Dans l'exemple ci-dessous, on cible tous les utilisateurs de l'Active Directory.
$HashTable = @{
1 = 'SCRIPT'
2 = 'ACCOUNTDISABLE'
8 = 'HOMEDIR_REQUIRED'
16 = 'LOCKOUT'
32 = 'PASSWD_NOTREQD'
128 = 'ENCRYPTED_TEXT_PWD_ALLOWED'
256 = 'TEMP_DUPLICATE_ACCOUNT'
512 = 'NORMAL_ACCOUNT'
2048 = 'INTERDOMAIN_TRUST_ACCOUNT'
4096 = 'WORKSTATION_TRUST_ACCOUNT'
8192 = 'SERVER_TRUST_ACCOUNT'
65536 = 'DONT_EXPIRE_PASSWORD'
131072 = 'MNS_LOGON_ACCOUNT'
262144 = 'SMARTCARD_REQUIRED'
524288 = 'TRUSTED_FOR_DELEGATION'
1048576 = 'NOT_DELEGATED'
2097152 = 'USE_DES_KEY_ONLY'
4194304 = 'DONT_REQ_PREAUTH'
8388608 = 'PASSWORD_EXPIRED'
16777216 = 'TRUSTED_TO_AUTH_FOR_DELEGATION'
67108864 = 'PARTIAL_SECRETS_ACCOUNT'
}
Get-ADUser -Filter * -Properties UserAccountControl |
Select-Object Name, UserAccountControl, @{
Name = 'Flags'
Expression = {
$uac = $_.UserAccountControl
$HashTable[$HashTable.Keys.Where{ $_ -band $uac }] -join '|'
}
}
Vous pouvez ajuster le filtre si vous voulez (un seul utilisateur, une OU cible, etc.). On obtient un résultat comme celui-ci :
En plus d'avoir la valeur décimale, il y a le nom des flags donc on peut interpréter facilement la valeur actuelle de l'attribut. Si vous souhaitez obtenir les informations pour les objets "ordinateurs", il suffit de remplacer Get-ADUser par Get-ADComputer.
D. Modifier l'attribut UserAccountControl avec PowerShell
En manipulant les cmdlets Set-ADUser et Set-ADComputer qui permettent respectivement de modifier les utilisateurs et les ordinateurs, on peut agir sur l'attribut UserAccountControl sans s'en rendre compte. En effet, il y a des paramètres intégrés qui agiront directement sur cet attribut, comme "-PasswordNeverExpires" qui permet de gérer l'option "Le mot de passe n'expire jamais" ou "-CannotChangePassword" correspond à "L'utilisateur ne peut pas changer de mot de passe".
Set-ADUser -Identity florian -PasswordNeverExpires $true
Mais, il y a un troisième cmdlet qui est capable d'agir sur l'attribut UserAccountControl : Set-ADAccountControl. Il fonctionne sur le même principe car si l'on veut activer l'option "Le mot de passe n'expire jamais", on doit utiliser :
Set-ADAccountControl -Identity florian -PasswordNeverExpires $true
Désormais, vous êtes en mesure de gérer l'attribut UserAccountControl et vous connaissez son utilité ! Si vous souhaitez vous amuser avec PowerShell et votre Active Directory, je vous recommande de lire mon cours : Administrer l'Active Directory avec PowerShell.
Excellent article 🙂
Bonjour,
dans le cas d’une liste restreinte d’utilisateurs, peut on juste lister les utilisateurs en les notant sous la forme [email protected] par exemple?