About the UserAccountControl attribute

Intro

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.

 

Bit definitions

Reference: https://support.microsoft.com/en-us/help/305144/how-to-use-the-useraccountcontrol-flags-to-manipulate-user-account-pro

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.

 

image

 

CSV table for download: UACBits

Composite values

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.

Decimal Hex Function
512 0x00000200 Normal account
514 0x00000202 Normal account, disabled
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
532480 0x00082000 Domain controller

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.

BITOR Examples

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.

BITOR(UserAccountControl, 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.

BITOR(UserAccountControl, 65536)

If we want to do both at the same time we just add them together 2^1 + 2^16 = 65 538

BITOR(UserAccountControl, 65538)

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:

image

BITAND examples

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:

image

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:

image

And the command is:

BITAND(-65537, UserAccountControl)

For enabling the account we want to set bit 1 to 0. The calculation : –1 – 2^1 = –3. And the command is:

BITAND(-3, UserAccountControl)

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)

 

 

 

 

Author: DizzyBadger

SQL DBA Principal Analyst

Leave a Reply