In Microsoft Exchange Server 5.5, you could perform most of your Exchange directory administration chores with relative ease if you had a good spreadsheet and knew how to use the Microsoft Exchange Administrator program's GUI. However, Exchange 2000 Server depends more on the tools available to support Active Directory (AD), so some old tricks and tools are no longer available. For example, the Microsoft Management Console (MMC) snap-ins used to administer Exchange and AD don't offer a bulk import/export utility; therefore, you can't use a directory export/import operation combined with Microsoft Excel to mass-manipulate mailbox properties.
As time goes on, both Microsoft and third-party developers will likely provide tools that let you perform many tasks. Meanwhile, let's look at how you can begin to build solutions for directory administration.
Fortunately, one of AD's core protocols is the Lightweight Directory Access Protocol (LDAP). Exchange 2000 uses LDAP in a variety of ways, and you'll soon find that LDAP can be a heavyweight tool if you understand how to use it. Let's look at what LDAP is and how you can use it to fill the administrative void in Exchange 2000 and even simplify some of Exchange Server 5.5's more difficult and tedious tasks.
What Is LDAP?
LDAP is a slimmed-down version of the X.500 Directory Access Protocol (DAP) specification. X.500 DAP is rarely used because it has an incredible amount of overhead associated with the functionality you must implement to be X.500 compliant. LDAP version 3 (LDAPv3) defines a standard way to query and update a directory. LDAP specifies the syntax to let you query directories (e.g., AD, the Exchange Server 5.5 directory) to retrieve attribute and configuration information and create and update information within that directory.
Table 1, page 2, defines some of the latest Internet Engineering Task Force (IETF) Request for Comments (RFCs) for LDAP. The Microsoft Developers Network (MSDN) and the Microsoft Windows 2000 Resource Kit have quite a bit of information about how to use LDAP with Microsoft products, so you don't necessarily need to read the RFCs to use LDAP. The RFCs will, however, give you a deeper understanding of how LDAP works and make it easier for you to define LDAP queries and troubleshoot LDAP problems.
Microsoft and LDAP
LDAP is a useful tool for administering both Exchange 2000/AD and Exchange Server 5.5 deployments because Exchange has included LDAP support since Exchange Server 5.0. Exchange Server 5.0 implemented LDAPv1, which specified only how to access directory information. Exchange Server 5.5 and AD support LDAPv3, which lets you both access and update directory information. Although Exchange Server 5.5 includes LDAP, LDAP isn't necessary for the Exchange directories to function. With AD, LDAP becomes a crucial component, and many of the administration tools use it. Therefore, if you understand how to use LDAP, you can
- Customize your Exchange 2000 Server deployments
- Integrate separate LDAP-capable systems
- Develop custom interfaces to administer Exchange 2000, Exchange Server 5.5, and AD
- Write small, one-time utilities to define or redefine some aspect of your system's directory
When you're building tools, Microsoft recommends that you access the LDAP API through Active Directory Service Interfaces. ADSI is a set of COM interfaces that give you access to a directory through a set of providers. One of these providers, the LDAP provider, gives you access to the Exchange Server 5.5 Directory Store or AD. Because ADSI is a set of COM interfaces, you can use any COM-capable programming language, such as VBScript, to access the directory. Figure 1 shows the relationship between your application, ADSI, LDAP, and the directories.
If you're working with an Exchange 2000 deployment, you already have access to ADSI because Windows 2000 includes ADSI. If you haven't begun to move to Win2K, you need to install ADSI 2.5 on the systems on which you'll run the applications you want to work with. You can download ADSI from http://www.microsoft.com/adsi. The installation is simple: The only prompt is to accept or decline the license agreement; no configuration is necessary.
Getting at Directory Data
To use ADSI and LDAP to work with directory data, you must perform the following steps:
- Specify an LDAP search string to locate a point in the directory hierarchy or a specific object within the directory.
- Read the attributes of one or more directory objects.
- Set, modify, or use the attribute information to perform tasks such as create a new mailbox, change the phone numbers in a department, or generate a report about each person's mailbox quota settings.
Let's look at the details of each step.
Specify the LDAP search string. With an LDAP search, you can access one item or all items in the directory. An LDAP search can have four elements: searchbase, filter, selection, and scope. The searchbase, filter, and selection elements are mandatory; the scope element is optional. You must use semicolons to separate the elements. No spaces can precede or follow the semicolons. For example, in the LDAP search string
LDAP://server/ou=Site,o=Org; (objectClass=Person);cn, distinguishedname,Home-MDB; Subtree
the search base LDAP://server/ou=Site,o= Org, for example, defines the starting point for the search (e.g., the root of your organization, a specific site or container, even a specific object within the directory). The filter (objectClass=Person) lets you define what objects you want the search to return. You usually use a filter to select a specific group of objects (e.g., all mailboxes). The selection determines what attribute information the query returns. In this example, cn,distinguished name,Home-MDB, returns the display name and distinguished name of the objects matching the query and the distinguished name of the Information Store (IS) that holds each object. Finally, the scope Subtree determines how the search progresses from the search base.
The choices for the scope are base, one level, or subtree. As Figure 2 shows, a search scope of Base causes the query to look only in or at the object the base component of the LDAP search string specifies; a one-level search searches the objects immediately below the base but doesn't include the base; and a subtree search searches the base and all objects below the base. The sidebar "LDAP Query Idiosyncrasies" provides some information about LDAP object names and other items you need to know about when you use LDAP and define your searches.
The structure of both the Exchange Server 5.5 Directory Store and AD is a hierarchy that the directory schema describes. Some attributes designate objects as containers; which make them capable of holding other objects and thus forming the hierarchy. Objects that aren't containers are referred to as leaf nodes. You can see this structure if you look at the hierarchy in Exchange Administrator. The Configuration object is a container that holds the Site Addressing object (a leaf node) and the Connections container. The Connections container then holds objects such as the Internet Mail Service (IMS) and Site connectors.
For LDAP to search, it needs to know which directory server to query and where in that directory to start looking. The search base provides this information. The search base usually takes a form similar to one of the following examples:
LDAP://server/cn=Object, cn=Container,ou=OrgUnit,o=Org LDAP://server/ou=Object, ou=OrgUnit,dc=Domain,dc=com LDAP://server/cn=Sub Container, cn=Container,ou=OrgUnit,o=Org LDAP://server/ou=Sub Org Unit, ou=OrgUnit,dc=Domain,dc=com
The first and second examples reference leaf nodes; the third and fourth examples reference containers that potentially contain many leaf-node objects. RFC 2533 defines that you specify the lowest point in the directory from the root node to the top of the directory (reading from right to left). The exact form you use depends on the directory structure of the LDAP server you're accessing. For example, the format
works with an Exchange Server 5.5 directory, and the format
works with AD.
The most complex and cryptic-looking part of an LDAP query is usually the filter. The filter specifies what you're trying to reference in the directory when your base doesn't specify a leaf-node object. The LDAP query from Exchange 2000 that generates the default address list, which Figure 3 shows, is a good example of a complex LDAP filter.
Although this string looks intimidating, it is fairly simple when you unwind it. In their most basic form, all LDAP filters have an attribute, a value, and some comparison operation enclosed in parentheses. For example, in Exchange Server 5.5, an LDAP filter
returns all mailbox objects, and an LDAP filter
(Proxy-Addresses=smtp:Joseph [email protected])
returns only one object, my mailbox.
Read the object's attributes. For most uses, LDAP filters must specify some combination of attributes and values to make the search meaningful. To specify attributes and values, the filter encloses each attribute and value set in a separate set of parentheses and uses another operator to logically combine the results. The most frequently used operators are AND (&), OR (|), and NOT (!).
For example, if you want to select all mailboxes in the Washington, D.C., area (i.e., Maryland and Virginia in addition to the District of Columbia), you create the LDAP filter
In this filter, (objectClass=organizational Person) specifies that only mailbox objects are selected; st is an LDAP definition for a state or province. When these terms are in parentheses and preceded by the | operator, the expression evaluates to "return any object that has one of these three values." Finally, surrounding the objectClass and state expressions with the & operator says that both the objectClass and one of the specified state expressions must be true to be included in the results list.
With regard to Exchange 2000's LDAP filter for the Global Address List, the GAL holds four types of objects: public folders, groups, contacts, and users. Each AD object has a category and a class attribute. You use the combination of these two attributes to determine an object's type. For public folders and groups, you can easily determine the object's type by looking at the objectCategory value. Because Exchange can contain Contacts as well as mail-enabled and non-mail-enabled users, which all have a person objectCategory, you must also examine the objectClass attribute.
If you stretch out the GAL's LDAP filter so that almost every logical and comparison operation is on a separate line, as Figure 4 shows, interpretation becomes easier. As you can see from the lines that define the Object Class attribute (objectClass), that attribute divides the person category into users and contacts. To determine whether a mailbox is enabled, you evaluate the homeMDB and msExchHomeServerName attributes.
The lines at callout A in Figure 4 select the mailbox-enabled and non-mailbox-enabled users, the lines at callout B select any group or public folder items, respectively, and the lines between callout A and callout B select the contact items. After these items have been selected from the directory, the & operation on the first line says that these items must also include a mailnickname (or email alias in Exchange Server 5.5 terminology) to be included in the LDAP query's results.
To define additional address lists or to modify the default address lists, you can change the LDAP filter. In the unlikely event that you want to add each computer object with a mailnickname to the GAL, insert (objectCategory=Computer) after callout B.
Use the attribute information to perform tasks. Using VBScript and the LDAP principles I've discussed here, you can create utilities that use LDAP to perform tedious or difficult tasks. Recently, I was working with a group that was joining an existing Exchange organization. The staff needed to change more than 700 distribution lists (DLs) to include a prefix on the display name and to remove SMTP addresses and leave only the X.400 addresses. We couldn't use Exchange Administrator to perform an import to make these changes because the site addressing specified both an SMTP and an X.400 address. When we did an import, the site-addressing specification kept causing the SMTP address to be recreated.
Our solution was to write a script to locate and modify the DLs. Listing 1 is an abbreviated version of that script. This version only modifies the display name; I've removed the code that obtains the addresses and keeps only the X.400 address.
The first nine lines of Listing 1 set up the ADSI objects needed to make the connection to the LDAP directory. Callout A in Listing 1 builds the LDAP query for identifying the DLs, excluding any DLs that have a Trust Level (Replication-Sensitivity) set to 100. The query includes all the LDAP query parts (i.e., searchbase, filter, selection, scope), separated by semicolons. The result of this query is a set of Exchange distinguished directory names that uniquely identify each DL. The core of the program uses these directory names to retrieve the objects to modify.
The next section loops through each DL object that the LDAP query returned. The code at callout B makes up the core of the program that performs the interesting LDAP update operations. The GetObject function moves the DL's attributes into a buffer. The put operation modifies the attribute, and SetInfo moves the changes from the buffer back into the directory, where they become permanent.
For More Information
I've given you some new information for using LDAP to make your systems better. If you want to begin to use LDAP through scripting, you can obtain more information from many sources. For VBScript examples, you can begin with the Win2K and BackOffice 4.5 resource kits. Both kits have examples that use LDAP to retrieve and update information. The sidebar "LDAP Resources" provides a few additional links.
If you decide to use LDAP to modify your directory settings, be careful. If you're not sure what you're doing, you can easily disable or corrupt your directory to the point where your only recourse will be a restore. However, if you use these techniques successfully, you can make your life easier.