Wildcard Active Directory Searches

by Marcin Policht

For system administrators, Active Directory Services Interface provides a way to access and manipulate various directory services (such as NT SAM, Netware Bindery and NDS, IIS metabase, Exchange Directory Services database, and Windows 2000 Active Directory or other third party LDAP-based directory stores). ADSI is a very powerful tool that hides the complexity of the underlying directory structure. The majority of account management tasks can be accomplished by writing simple, short scripts. These include creating and deleting users as well as modifying their properties (such as password, expiration date, profile, home directory, logon script, group membership, etc.) The Active Directory Services Interface (ADSI) is a powerful tool that hides the complexity of the underlying directory structure while also providing a way to access and manipulate various directory services. This article discusses wildcard searches in the ADSI and includes a sample script for the task.

There are, however, tasks that involve a bit more effort to automate. One of them is implementing wildcard searches of Active Directory (such as searching for names containing a particular string of characters). This can be accomplished by employing another set of COM interfaces called ActiveX Data Objects (or ADO in short).

ADO, in its current implementation, uses a low-level OLE DB provider to simplify access to various databases. It also is capable of representing structured information stores, such as directory services databases, in a form that yields itself to typical database operations, such as queries.

The queries used for accessing Active Directory can be written in one of two formats (also called dialects):

Dialect A: LDAP - consisting of four parts separated by semicolons:

1) Base distinguished name determining Active Directory container to search e.g.
<LDAP: DC="swynk,DC=com">

2) LDAP search filter indicating criteria for search e.g.(&(objectCategory=person)(sn=Jsmith)). The filter can include wild cards(*) e.g. (&(objectCategory=person)(cn=*admin*))

3) Attributes to be returned from the query e.g. profilePath, telephoneNumber, etc.

4) Search scope e.g. base (search of the base container only), one-level (one-level deep search), or subtree (searching all subcontainers of the base container)

For example, the following statement will search for all users with the last name starting with "Pol" and return the path of the user account object, last name, first name, and telephone number:

strQuery = "<LDAP://" & strDomain&">;(&(objectClass=user)(sn=Pol*));ADsPath,sn,givenName,telephoneNumber;subtree"

where strDomain is a variable containing the name of the domain where the user accounts reside.

Dialect B: SQL - constructed like a typical SQL (or Transact-SQL) statement and consisting of the following keywords:

1) SELECT - followed by comma-separated list of attributes to be returned e.g. profilePath, telephoneNumber, etc.

2) FROM - followed by AD's path of the search e.g.'LDAP://CN=users,DC=swynk,DC=com'

3) WHERE - followed by filter criteria, based on one of selected attributes.

The SQL query analogical to the one written using LDAP dialect would take the form:

strQuery = "SELECT ADsPath, sn, givenName, telephoneNumber FROM 'LDAP://DC=" & strDomain & ",DC=com' WHERE sn = 'Pol*'"

With the exception of the query format, a script implementing the search would be identical in both cases.

The sample script that follows searches domain swynk.com for user accounts starting with the string "Pol".

The script first creates the Connection object. This object represents a unique session with a data source (Active Directory in our case). The provider property of this object needs to be set to the string "ADsDSOOBJECT" representing the OLE DB provider. Next, Open method needs to be called. Once the connection is open, you can run either query (using LDAP or SQL dialect). The query populates a structure called a RecordSet, where results satisfying specified criteria are stored. MoveNext method of the RecordSet object is used in a While loop to list all results.

Dim objConn, objRecordSet
Dim strDomain, strQuery

strDomain = "swynk"
Set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOOBJECT"
strQuery = "<LDAP://" &strDomain&">;(&(objectClass=user)(sn=Pol*));ADsPath,sn,givenName,telephoneNumber;subtree"
'strQuery = "SELECT ADsPath, sn, givenName, telephoneNumber FROM 'LDAP://DC=" & _ 
'                                                                         strDomain & ",DC=com' WHERE sn = 'Pol*'"
Set objRecordSet = objConn.Execute(strQuery)

While Not objRecordSet.EOF 
   WScript.Echo "Name: " & objRecordSet.Fields("givenName") & " " & _
      objRecordSet.Fields("sn") & vbCrLF & _
      "Telephone Number: " & objRecordSet.Fields("telephoneNumber") & vbCrLf & _
      "ADsPath: " & objRecordSet.Fields("ADsPath") & vbCrLf & vbCrLf

The script will list all the full names of user account with last names starting with "Pol", as well as their telephone numbers and the full ADSI path of each user account object in Active Directory.

This article was originally published on Jun 27, 2001
Page 1 of 1

Thanks for your registration, follow us on our social networks to keep up-to-date