When working with MIM you will sooner or later have to deal directly with the UserAccountControl Active Directory attribute. This attribute defines account options, and we use it most prevalently to enable and disable users, but there are a lot of other options as well. These options are stored in a binary value as bit flags, where each bit defines a specific function.
Bit number 1 (or 2 if you are not used to zero-based numbering) defines whether or not an account is enabled. Bit number 9 defines an account as a normal account. Thus, a normal disabled account will have bits 1 and 9 set to one. As long as no other bits are set, the decimal value is 2^9 + 2^1 = 514 or (0010 0000 0010). If we enable the account, the value is 2^9 = 512 (0010 0000 0000).
In MIM we are usually presented with decimal values. These are easier to read, but not necessarily easier to understand.
The table below is augmented with bit position numbers and a full binary readout. Some bits do not have a documented function, in those cases function is left blank in the table.
CSV table for download: UACBits
This table lists some composite values I have come across in the field. The plan is to extend this table as I find new ones.
|514||0x00000202||Normal account, disabled|
|544||0x00000220||Normal account, password not required|
|546||0x00000222||Normal account, disabled, password not required|
|4096||0x00001000||Computer account (Workstation/server)|
|66048||0x00010200||Normal account, password never expires|
|66050||0x00010202||Normal account, disabled, password never expires|
|66080||0x00010220||Normal account, password never expires, password not required|
|66082||0x00010222||Normal account, disabled, password never expires, password not required|
Manipulating values with BITAND and BITOR
When we want to change a value, we usually do this with BITAND and BITOR. These are logical bit-wise operations, and you can read more about how they work here: https://social.technet.microsoft.com/wiki/contents/articles/22114.fim-reference-how-to-enabledisable-an-ad-account-and-set-other-uac-flags-in-a-declarative-sync-rule.aspx.
In short, we use BITOR to flip a bit to 1 and BITAND to flip it to 0.
When we do a logical or, we compare two bits and return 1 of any or both values are 1. That is:
- 1 or 1 = 1
- 1 or 0 = 1
- 0 or 1 = 1
- 0 or 0 = 0
If we want to disable a user by setting bit 1 to 1, we would use 2^1 = 2.
If we want to enable Password Never Expires, because who cares about security and what not, we have to set bit 16. That is 2^16 = 65 536.
If we want to do both at the same time we just add them together 2^1 + 2^16 = 65 538
Used correctly no other bits will change as a result of this command. You can check the results in AD Users and Computers or ADSI Edit:
Setting a bit to 0 is a bit more complicated.We want to make sure that none of the other bits are changed during the process, and we do not necessarily know which ones are set to 0 and which ones are set to 1…
When we do a logical and, we compare two and two bits and return 1 if both bits are one. That is:
- 1 and 1 = 1
- 1 and 0 = 0
- 0 and 1 = 0
- 0 and 0 = 0
First, we have to know how many bits there are. Bit 26 is the most significant documented bit, so I assumed that it was a 32-bit value. The FIM reference confirms this to be true. Furthermore, we know that it is a Two’s complement signed number. That is a fancy way of saying that the most significant bit (number 31 in the table above) is 0 for positive values and 1 for negative values. As such, if all 32 bits are set to 1, the result in decimal is –1. You can play with these numbers in the windows calculator in DWORD (32bit) programming mode:
If we want to clear bit 16 to disable password never expires, we have to calculate the decimal equivalent of 1111 1111 1111 1110 1111 1111 1111 1111. We could of course just writ this into the calculator, but that is a lot of numbers and a high risk of mistakes. Instead, we can do the following:
-1 – 2^16 = –65 537. You can then input this value into the calculator to check the result:
And the command is:
For enabling the account we want to set bit 1 to 0. The calculation : –1 – 2^1 = –3. And the command is:
If we combine both of them to disable password never expires and enable the user we want to set both bit 16 and 1 to 0. we just add them together like this: –1 – 2^16 – 2^1 = –65 539. And the command is:
BITAND(-65 539, UserAccountControl)