Edit September 4 2015, added link to useraccountcontrol explanation. Thanks Richard Stebbings for the URL!
Every once in a while we take a look at out Active Directory and do checks, a lot checks. One of these checks consists of investigating the UserAccountControl attribute value on the user accounts. As it turns out you can get some unexpected results when running these checks.
First of all, let’s take a look at the UserAccountControl attribute itself. Many of you probably know UserAccountControl as the pop-up screen on windows that was introduced with Windows Vista. Well, this is something different.
So what is this UserAccountControl attribute. Basically, the UserAccountControl attribute holds the state of the account. The UserAccountControl attribute is an integer where each bit corresponds to a different setting. Whether it is disabled, requires DES, Kerberos Pre-authentication, if the password is expired and so forth. Below is a list of the available values.
Now, one thing that came out of the report was that some user accounts were not forced to require a password. Wait what? No password requirement? That could be a major security risk. This particular setting can be found by searching for value 32 on this attribute. But how do we search for such a thing? Well since this is a Powershell blog, you probably already guessed how we are going to do that, that’s correct Powershell. I’ll show you a few ways how to accomplish this.
The easiest (and probably best) way is to simply use the Active Directory module supplied by Microsoft.
Pretty straight forward. What we are doing is retrieving the users from ActiveDirectory where the UserAccountControl contains the value 32. But how does this work?
The “-band” is a so-called bitwise operator. Band actually stands for “Bitwise and”. Meaning that if the bitwise value of the attribute contains 32 it returns true and is displayed. But where do we get that value ’32’ from? As you can see in the earlier mentioned Table the decimal value of 32 stands for ‘password not required’. If we convert 32 decimal to hexadecimal the value changes to 20 of actually 0x20. When we convert this value to binary we get 0x100000.
The Microsoft site displays all the values in Hexadecimal. I prefer to look at it in Binary for one particular reason. Binary can only be 0 or 1. So basically what this does is act like a switch. I’m now counting from the left so when I mention the first Bit I mean the first from the right. 32 is the 6th bit. Now value 1 means the associated property is active, 0 means it is inactive. This way it is possible to determine the effective account settings by the value that’s in the UserAccountControl field.
Ok, so when we have run the query we may get a list of accounts that do not require a password (by default the guest account is in there). Now how do we solve this. This is pretty easy as well with the ActiveDirectory module. For this we need the Set-ADAccountControl cmdlet.
You may receive an error with the set-adaccountcontrol attribute stating the current password does not meet complexity requirements. We found that manually changing the password solves this, however we are not 100% sure about the cause. We suspect the cmdlet cannot read the password and therefore cannot even determine if complexity requirements are met. The only thing it can detect is an empty value, meaning there is no password in place at all. We have seen this behaviour on Windows server 2008 DC’s but when I was testing it again for this blogpost I could not reproduce it on a 2012 R2 DC.
Now, what if you do not have Domain Controllers running at least Windows Server 2008 R2 and do not have the AD Webservices in place? You cannot use the active directory module that way. Fortunately there are alternatives. You may want to take a look at the quest Activeroles activedirectory management snapin. Quest did a really great job with this snapin way before Microsoft introduced the active directory module. One small downside is we cannot use the -band operator with these cmdlets, however there is an ldapfilter possibility. So to get a list of all users not requiring a password by using the quest cmdlets run the following command.
As you can see the ldapfilter has the possibility of doing bitwise operators. However the naming is a bit user unfriendly to say the least. You can find more on the ldap bitwise operators Here
It is possible to use the quest cmdlets to correct the value, however directly editing the useraccountcontrol value is not a best practice. There is an alternative way would be to use the net user command.
That’s it for now, thank you for reading. If you have any questions, please feel free to contact me.