When using Active Directory (AD) as a source of user data, it’s useful to filter out disabled accounts. Unfortunately, AD has a lot of different security-related settings glomed together in the userAccountControl attribute. Which means there’s no single attribute/value combination you can use to ignore disabled accounts.
The decimal value you see for userAccountControl isn’t terribly useful, but display it in binary and each bit position has a meaning. The userAccountControl value is just the number with a bunch of bits set. Numbering the bits from left to right, here is what each one means.
Bit # | Meaning |
0 | Unused – must be 0 |
1 | Unused – must be 0 |
2 | Unused – must be 0 |
3 | Unused – must be 0 |
4 | Unused – must be 0 |
5 | ADS_UF_PARTIAL_SECRETS_ACCOUNT |
6 | ADS_UF_NO_AUTH_DATA_REQUIRED |
7 | ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION |
8 | ADS_UF_PASSWORD_EXPIRED |
9 | ADS_UF_DONT_REQUIRE_PREAUTH |
10 | ADS_UF_USE_DES_KEY_ONLY |
11 | ADS_UF_NOT_DELEGATED |
12 | ADS_UF_TRUSTED_FOR_DELEGATION |
13 | ADS_UF_SMARTCARD_REQUIRED |
14 | Unused – must be 0 |
15 | ADS_UF_DONT_EXPIRE_PASSWD |
16 | Unused – must be 0 |
17 | Unused – must be 0 |
18 | ADS_UF_SERVER_TRUST_ACCOUNT |
19 | ADS_UF_WORKSTATION_TRUST_ACCOUNT |
20 | ADS_UF_INTERDOMAIN_TRUST_ACCOUNT |
21 | Unused – must be 0 |
22 | ADS_UF_NORMAL_ACCOUNT |
23 | Unused – must be 0 |
24 | ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |
25 | ADS_UF_PASSWD_CANT_CHANGE |
26 | ADS_UF_PASSWD_NOTREQD |
27 | ADS_UF_LOCKOUT |
28 | ADS_UF_HOMEDIR_REQUIRED |
29 | Unused – must be 0 |
30 | ADS_UF_ACCOUNT_DISABLE |
31 | Unused – must be 0 |
Bit #30 indicates if the account is disabled — 1 if the account is disabled, 0 if the account is enabled. Simple and direct approach is to “and” the attribute value with 0b10 to extract just the bit we care about. When the and operation returns 0, the account is enabled. When it returns 2 (0x10), the account is disabled.
A list of userAccountControl values and the corresponding meaning:
userAccountControl Value | Meaning |
1 | Logon script executes |
2 | Account Disabled |
8 | Home Directory Required |
16 | Lockout |
32 | Password Not Required |
64 | User cannot change password |
128 | Encrypted text password not allowed |
256 | Temporary Duplicate Account |
512 | Normal active account |
514 | Normal disabled account |
544 | Password not required, enabled account |
546 | Password not required, disabled account |
2048 | Inter-domain trust account |
4096 | Workstation trust account |
8192 | Server trust account |
65536 | No password expiry |
66048 | Password never expires, enabled account |
66050 | Password never expires, disabled account |
66082 | Password never expires and is not required, enabled account |
66084 | Password never expires and is not required, disabled account |
131072 | MNS Login account |
262144 | Smartcard required |
262656 | Smartcard required, enabled account |
262658 | Smartcard required, disabled account |
262688 | Enabled account, password not required, smartcard required |
262690 | Disabled account, password not required, smartcard required |
328192 | Enabled account, password doesn’t expire, smartcard required |
328194 | Disabled account, password doesn’t expire, smartcard required |
328224 | Enabled account, password doesn’t expire, password not required, smartcard required |
328226 | Disabled account, password doesn’t expire, password not required, smartcard required |
524288 | Trusted for delegation |
532480 | Domain controller |
1048576 | Not delegated |
2097152 | Use DES key only |
4194304 | Don’t require pre-authorization |
8388608 | Password expired |
16777216 | Trusted to auth for delegation |
67108864 | Partial secrets account |