A common issue faced by Active Directory administrators, particularly those who want to extend their administrative
skills into command-line or scripting automation, is in developing an understanding of how to create Lightweight Directory Access Protocol (LDAP) queries. Since Active Directory is based on the LDAP standard (defined in RFC 2251), you can use just about any LDAP-compliant tool to work with the information stored in your Active Directory database. If you've ever searched for information using the Active Directory Users & Computers MMC snap-in, you've already seen an LDAP search in action, working behind the scenes to retrieve the information you requested.
To exert more granular control when searching AD, you can use VBScript or a tool like dsquery or adfind to search for Active Directory objects that meet very specific criteria. This is where admins who are new to command-line and scripting tools will sometimes get a bit unsettled when faced with something like this:
adfind –b dc=mycompany,dc=com –s subtree -f
The good news is that this seemingly arcane syntax is fairly simple to understand once you break it down into its component pieces. A correctly-formed LDAP query involves three main components:
1. You'll start by specifying the search base. This specifies where in the Active Directory structure the query should begin its search, using the Distinguished Name (DN) syntax. So to search within the mycompany.com domain naming context, you would use a search base of dc=mycompany, dc=com. To search the Configuration NC, you would specify cn=Configuration followed by the forest root DN, since there is only one Configuration NC for an entire forest. (This would look something like cn=Configuration, dc=mycompany, dc=com.) Likewise, searching the Schema NC would require a search base of cn=Schema, cn=Configuration followed by the forest root DN.
Most Active Directory search tools will provide shortcut operators that will allow you to save some typing when you want to search the Schema, Configuration, or Domain NC. Adfind, for example, provides the following shortcuts:
- adfind –default will search the default domain NC
- adfind –schema will search the schema NC
- adfind –config will search the configuration NC
Similarly, the built-in Microsoft tool dsquery provides shortcut operators to search the domain NC and the forest root NC, using dsquery domainroot and dsquery forestroot, respectively.
2. Your next step is to specify the search scope. While the search base specifies where to start your search, the search scope specifies how far or how "deep" into the directory tree to search. You have three options when specifying the scope of an LDAP search:
- base. This will search only the object that you specified in the search base, without searching any child containers. For example, if you specify a base-scoped search of cn=Configuration, dc=mycompany, dc=com, the search will return only the Configuration object itself, but not any objects contained within the container or any of its child containers.
- onetree. This will search the objects that are located immediately beneath the container specified in the search base, but will not search the base object. So a onetree-scoped search of the ou=Finance, dc=mycompany, dc=com container will search the ou=Payroll, ou=Finance, dc=mycompany, dc=com container, but will not search the Finance OU itself.
- subtree This will search the entire subtree underneath the specified search base, including the base object itself. A subtree-scoped search of the ou=Finance, dc=mycompany, dc=com container will search all nested OUs contained within the Finance OU, as well as the Finance OU itself. This is the default search scope for most search tools; if you do not specify a scope, tools like adfind and dsquery will perform a subtree-scoped query.
3. Finally, you need to specify the search filter, which indicates what types of objects you are searching for. A simple '*' in adfind or '*.' using most other LDAP tools will return all objects contained within the search base and search scope that you specified, or you can use as simple or as complex of a search filter as you need to pinpoint the desired results. (The '*' filter in adfind converts '*' to 'objectclass=*'.) Some examples of common search filters include the following:
- Querying a particular site's DN using the (objectcategory=ntdsdsa) filter will return all domain controllers within that site. This filter specifies only a single criterion.
- Querying a domain or an OU using the "(&(objectcategory=person)(objectclass=user))" filter will return all users within a particular container. This filter specifies multiple criteria, and the "(&" portion of the filter means that "AND" should be used. In other words, only objects that meet both criterion in the filter will be returned. If you use "(|" instead, this will create an "OR" filter, where the filter will return objects that meet one or more criteria, but not necessarily all of them.
Even in a small environment, having an understanding of LDAP queries is a useful skill for an administrator to possess, and in a large enterprise environment it's practically essential. For an in-depth look at LDAP, you can download the following white paper from the Microsoft website, as well as the following interactive training tool and Powerpoint deck on the Technet site.
ABOUT THE AUTHOR
Laura E. Hunter (CISSP, MCSE: Security, MCDBA, Microsoft MVP) is a senior IT specialist with the University of Pennsylvania, where she provides network planning, implementation and troubleshooting services for business units and schools within the university. Hunter is a two-time recipient of the prestigious Microsoft "Most Valuable Professional" award in the area of Windows Server-Networking. She is the author of the Active Directory Field Guide (APress Publishing). You can contact her at firstname.lastname@example.org.