Last modified at 11/2/2013 9:13 PM by Koen Zomers

It is possible to use PowerShell to set the UserAccountControl flags on an user object in Active Directory. In the Active Directory Users and Computers maintenance tool, these settings translate to the Account options on the Account tab:

PowerShell-ADSI-UserAccountControlFlags-ObjectProperties.png

In Active Directory these checkboxes are stored in the attribute "userAccountControl" of the User object. You can easily view its contents by using ADSI Edit:

PowerShell-ADSI-UserAccountControlFlags-UserAccountControlField.png

This field contains a numeric value. Based on the options being set/checked, this value will increase or decrease.

Possible values

An overview of the possible options and their equivalent numeric option are (source):

Property flagValue in hexadecimalValue in decimal
SCRIPT0x00011
ACCOUNTDISABLE0x00022
HOMEDIR_REQUIRED0x00088
LOCKOUT0x001016
PASSWD_NOTREQD0x002032
PASSWD_CANT_CHANGE
Note You cannot assign this permission by directly modifying the UserAccountControl attribute. For information about how to set the permission programmatically, see the "Property flag descriptions" section.
0x004064
ENCRYPTED_TEXT_PWD_ALLOWED0x0080128
TEMP_DUPLICATE_ACCOUNT0x0100256
NORMAL_ACCOUNT0x0200512
INTERDOMAIN_TRUST_ACCOUNT0x08002048
WORKSTATION_TRUST_ACCOUNT0x10004096
SERVER_TRUST_ACCOUNT0x20008192
DONT_EXPIRE_PASSWORD0x1000065536
MNS_LOGON_ACCOUNT0x20000131072
SMARTCARD_REQUIRED0x40000262144
TRUSTED_FOR_DELEGATION0x80000524288
NOT_DELEGATED0x1000001048576
USE_DES_KEY_ONLY0x2000002097152
DONT_REQ_PREAUTH0x4000004194304
PASSWORD_EXPIRED0x8000008388608
TRUSTED_TO_AUTH_FOR_DELEGATION0x100000016777216
PARTIAL_SECRETS_ACCOUNT0x04000000  67108864

Manually calculate the values

You can easily calculate what options have been set based on the number being shown in the userAccountControl attribute. In the screenshot above you'll see it's currently set to 0x200 on my test account. As you can read in the table above, this translates to normal_account. If we would also set the account to be disabled, the value of userAccountControl would be 512 + 2 = 514 decimal. To calculate this decimal value back to it's equivallent properties, simply take the highest possible number in the table above which fits in the decimal value. In this case that would be 512 which stands for normal_account. Deducting our 514 value with the 512 we use for this normal_account flag, leaves us with 2 decimal. The biggest number of the table above which fits this leftover number is accountdisabled which is 2. Deducting this from the decimal value leaves us with 0, meaning we have defined all flags represented by the decimal number in our userAccountControl attribute.

Using PowerShell

With PowerShell, its easy to do this value to flag translation and to set or remove flags. I'll show how to do this.

You start with getting a reference to the User Object in Active Directory you want to examine. There are many ways of doing so. I'll show the two most common ones: by referring directly to its fully distinguished name and by searching by its username (sAMAccountName).

Getting an user account reference by its fully distinguished name (FQDN)

To get an user object instance by it's FQDN, you can execute the following PowerShell script. One way to get the FQDN of an user object is to use ADSI Edit:

PowerShell-ADSI-UserAccountControlFlags-ADSIEditFQDN.png

Assuming my domain is called test.local (the part I blacked out), this would translate into the following line of PowerShell:

$user = [ADSI] "LDAP://CN=Koen Zomers,CN=Users,DC=test,DC=local"

Continue reading below to see how we can use this instance to handle its userAccountControl flags.

Getting an user account reference by its account name

Another way of getting an user object from Active Directory is by searching for an object based on the account name, also indicated as sAMAccountName. This can be done with the following lines of PowerShell:

$accountName = "koenzomers"
$adsiSearcher = New-Object DirectoryServices.DirectorySearcher [ADSI]$null
$adsiSearcher.filter = "(&(objectClass=user)(sAMAccountName=$accountName))
$adsiSearcherResult = $adsiSearcher.FindOne()
$user = $adsiSearcherResult.GetDirectoryEntry()

Continue reading below to see how we can use this instance to handle its userAccountControl flags.

Reading the userAccountControl flags from the user object instance

By using one of the two methods above, you now have an Active Directory user object stored under $user. We can now query its active flags by running this line of PowerShell:

$user.userAccountControl[0]

It returns us the decimal value of all the flags that are set on this user object, i.e. 514 when the normal_account and accountdisabled flags are set.

Checking if a particular flag has been set on the user object instance

If you want to check if a particular flag has been set on our $user instance, you can run the following line of PowerShell:

($user.UserAccountControl[0] -band <decimal value of flag>) -ne 0

For example to check if the user account is disabled (accountdisabled should be present, decimal value 2):

($user.UserAccountControl[0] -band 2) -ne 0

This returns $true if the flag is set (thus the account is disabled) or $false if the flag has not been set (thus the account is enabled). The same can be done for any of the other flags listed in the table above.

Removing a flag from the user object instance

If you want to remove a flag, you can simply deduct its decimal value from the current value of userAccountControl. Make sure the flag is currently set on the user account before doing so though, otherwise it will mess up all of your flags. To enable a currently disabled account, you can run the following line of PowerShell:

# Check if the useraccountdisabled flag (decimal value 2) is currently set on the userobject
if((($user.userAccountControl[0] -band 2) -ne 0) -eq $true)
{
   # Remove the useraccountdisabled flag (decimal value 2)
   $user.userAccountControl[0] -= 2
   # Save the new value in the user object
   $user.SetInfo()
}

To disable a currently enabled account, you can run:

# Check if the useraccountdisabled flag (decimal value 2) is currently set on the userobject
if((($user.userAccountControl[0] -band 2) -ne 0) -eq $false)
{
   # Add the useraccountdisabled flag (decimal value 2)
   $user.userAccountControl[0] += 2
   # Save the new value in the user object
   $user.SetInfo()
}

Obviously you can replace the decimal value 2 in the if statement and the value increase/decrease for any of the other values listed in the table above.