Querying BITWISE flags in attributes
As you know several attributes in the Active Directory are composed of BITWISE flags. This means that the attribute consists of several flags which may be (or may be not) set on the attribute, and querying these attributes may sometimes be a real pain…
The main purpose of this post is to present the LDAP_MATCHING_RULE_BIT_AND control, and how to use it when querying those bitwise flags in attributes.
Let look at the UserAccountControl attribute for example, this attribute controls the behavior of the user account.
In the msdn page describing the attribute you can find a full list of all possible flags for the attribute (http://msdn.microsoft.com/en-us/library/ms680832(VS.85).aspx).
Let’s look at some of the flags:
0x00000200 ADS_UF_NORMAL_ACCOUNT This is a default account type that represents a typical user.
0x00010000 ADS_UF_DONT_EXPIRE_PASSWD The password for this account will never expire.
0x00000002 ADS_UF_ACCOUNTDISABLE The user account is disabled.
Now let’s say we have a normal user account (userAccountControl flag set to 0x200 which is 512 decimal) which looks like this:
And then we set the password never expires flag (which is 0x10000) , so together we’ll get 0x10200 (which is 66048 decimal). This would look something like the following:
So now the interesting part starts – if we also disable the account we will get the value of 0x10000 + 0x200 + 0x2= 0x10202 (66050 decimal).
Right, so far so good… now i want to query all user accounts in the domain set with password never expires flag (regardless if they are enabled or disabled) ….
Huh??? query what??? why??? no… sorry… well…. hmmmm…. (sounds like a proper response to such a request, wouldn’t it? :) ).
While making all this sounds and vowels the thoughts going inside the head are: “Querying for userAccountControl=66048 wouldn’t get the disabled accounts, while querying for 66050 wouldn’t get the enabled accounts.”
So what’s the solution to the problem??
Query the specific BIT you want!
Active Directory provides a control in order to query specific bits of a flag - 1.2.840.113556.1.4.803 (LDAP_MATCHING_RULE_BIT_AND).
Constructing the query is easy, you just have to query the attribute (userAccountControl) with the flag you need (ADF_UF_DONT_EXPIRE_PASSWD – 0x10000 in decimal – 65536) .
So using the provided example I will be able to query for all accounts with password never expires flag set by the following LDAP query - (&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))
How do you do that using a script?
Here’s a sample powershell script:
$strFilter = "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))"
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = $strFilter
$objSearcher.SearchScope = "Subtree"
$colResults = $objSearcher.FindAll()
foreach ($objResult in $colResults)
{$objResult.path}
Hope this helps in querying the BITWISE attributes
Comments
- Anonymous
November 14, 2013
Thank you for posting this which is very helpful.