You want to search against an attribute that contains a bit flag and you need to use a bitwise filter.
Follow the directions in Recipe 4.5 for searching for objects.
For the Filter, enter the bitwise expression, such as the following, which will find all universal groups:
(&(objectclass=group)(objectCategory=group)(groupType:1.2.840.113556.1.4.804:=8))
Click Run.
The following query finds universal groups using a bitwise OR filter:
> dsquery * cn=users,dc=rallencorp,dc=com -scope subtree -attr "name" -filter[RETURN]
"(&(objectclass=group)(objectCategory=group)(groupType:1.2.840.113556.1.4.804:=8) )"
The following query finds disabled user accounts using a bitwise AND filter:
> dsquery * cn=users,dc=rallencorp,dc=com -attr name -scope subtree -filter[RETURN] "(&(objectclass=user)(objectcategory=person)(useraccountcontrol:1.2.840.113556.1.4.[RETURN] 803:=514))"
' The following query finds all disabled user accounts strBase = "<LDAP://cn=users,dc=rallencorp,dc=com>;" strFilter = "(&(objectclass=user)(objectcategory=person)" & _ "(useraccountcontrol:1.2.840.113556.1.4.803:=514));" strAttrs = "name;" strScope = "subtree" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) objRS.MoveFirst while Not objRS.EOF Wscript.Echo objRS.Fields(0).Value objRS.MoveNext wend
Many attributes in Active Directory are composed of bit flags. A bit
flag is often used to encode properties about an object into a single
attribute. For example, the groupType
attribute on
group
objects is a bit flag that is used to
determine the group scope and type.
The userAccountControl
attribute on
user
and computer
objects is
used to describe a whole series of properties, including account
status (i.e., enabled or disabled), account lockout, password not
required, smartcard authentication required, etc.
The searchFlags
and systemFlags
attributes on attributeSchema
objects define,
among other things, whether an attribute is constructed, indexed, and
included as part of Ambiguous Name Resolution (ANR).
To search against these types of attributes, you need to use bitwise search filters. There are two types of bitwise search filters you can use, one that represents a logical OR and one that represents logical AND. This is implemented within a search filter as a matching rule. A matching rule is simply a way to inform the LDAP server (in this case, a domain controller) to treat part of the filter differently. Here is an example of what a matching rule looks like:
(userAccountControl:1.2.840.113556.1.4.803:=514)
The format is
(attributename
:MatchingRuleOID
:=value
).
As I mentioned, there are two bitwise matching rules, which are
defined by OIDs. The logical AND matching rule OID is
1.2.840.113556.1.4.803 and the logical OR matching rule OID is
1.2.840.113556.1.4.804. These OIDs instruct the server to perform
special processing on the filter. A logical OR filter will return
success if any bit specified by value
, is
stored in attributename
. Alternatively,
the logical AND filter will return success if all bits specified by
value
, match the value of
attributename
. Perhaps an example will
help clarify this.
To create a normal user account, you have to set
userAccountControl
to 514. The number 514 was
calculated by adding the normal user account flag of 512 together
with the disabled account flag of 2 (512 + 2 = 514). If you use the
following logical OR matching rule against the 514 value, as shown
here:
(useraccountcontrol:1.2.840.113556.1.4.804:=514)
then all normal user accounts (flag 512) OR disabled accounts (flag
2) would be returned. This would include enabled user accounts (from
flag 512), disabled computer accounts (from flag 2), and disabled
user accounts (from flag 2). In the case of
userAccountControl
, flag 2 can apply to both user
and computer accounts and, hence, why both would be included in the
returned entries.
One way to see the benefits of bitwise matching rules is that they allow you to combine a bunch of comparisons into a single filter. In fact, it may help to think that the previous OR filter I just showed could also be written using two expressions:
(|(useraccountcontrol:1.2.840.113556.1.4.804:=2) (useraccountcontrol:1.2.840.113556. 1.4.804:=512))
Just as before, this will match userAccountControl
attributes that contain either the 2 or 512 flags.
For logical AND, similar principles apply. Instead of any of the bits
in the flag being a possible match, ALL of the bits in the flag must
match for it to return a success. If we changed our
userAccountControl
example to use logical AND, it
would look like this:
(useraccountcontrol:1.2.840.113556.1.4.803:=514)
In this case, only normal user accounts that are also disabled would
be returned. The same filter could be rewritten using the
&
operator instead of |
as
in the following:
(&(useraccountcontrol:1.2.840.113556.1.4.803:=2) (useraccountcontrol:1.2.840.113556.1.4.803:=512))
An important subtlety to note is that when you are comparing only a single bit-flag value, the logical OR and logical AND matching rule would return the same result. So if we wanted to find any normal user accounts we could search on the single bit flag of 512 using either of the following:
(useraccountcontrol:1.2.840.113556.1.4.803:=512) (useraccountcontrol:1.2.840.113556.1.4.804:=512)
Get Active Directory Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.