ADSI Application

The best way to learn about using ADSI to program with the Exchange Server directory is to examine a sample application. I developed one that demonstrates how to create mailboxes, custom recipients, distribution lists, and recipient containers, and how to query for recipient directory information such as a user's name, address, and phone number. There is one caveat with this application—since it uses DHTML to mimic the Exchange Administrator program, the portion of the application that queries the attributes of a specific user will not work with Netscape browsers and will work only in Microsoft Internet Explorer 4.0.

Setting Up the ADSI Application

Before you can install the application, you must have a Windows NT 4.0 Server and a client with certain software installed. Table 14-1 describes the required software for setting up the application.

Table 14-1 Installation Requirements for the ADSI Application

Required Software Installation Notes
Exchange Server 5.5 SP1 with Outlook Web Access
IIS 3.0 or higher with Active Server Pages IIS 4.0 is recommended.
CDO library (cdo.dll)
CDO Rendering library (cdohtml.dll)
Exchange Server 5.5 SP1 installs CDO library 1.21 and CDO Rendering library 1.21. Outlook 98 installs CDO library 1.21.
ADSI 2.0 ADSI 2.0 is available as a free download from http://www.microsoft.com/backoffice/downloads.htm.
ActiveX Data Objects IIS 4.0 installs ADO 1.5. Visual Basic 6.0 installs ADO 2.0. For more information on ADO, consult http://www.microsoft.com/data/.
For the client:
Internet Explorer 4.0
Outlook 98
You can run the client software on the same machine or on a separate machine.

To install the ADSI application, first copy the ADSI folder from the companion CD to your web server where you want to run the application. Start the IIS administration program. Create a virtual directory that points to the location where you copied the ADSI files, and name the virtual directory adsi. Make sure you enable the Execute permissions option for the virtual directory. You will be able to use the following URL to access your ADSI application: http://yourservername/adsi.

Included with the ADSI files is a DLL named AcctCrt.dll. Use the Regsvr32 utility to register it:

 regsvr32 acctcrt.dll 

The first page displayed in the ADSI application is the logon page, as shown in Figure 14-3. Once a user enters logon information and verifies the dynamically generated Exchange Server information, the application presents a menu of available administrative options for the user, as shown in Figure 14-4.

click to view at full size.

Figure 14-3 The Logon page for the ADSI application. The Exchange Server name, organization, and site information are pulled dynamically using the CDO Rendering library.

click to view at full size.

Figure 14-4 The main menu of the ADSI application. Users can create or modify objects in the Exchange Server directory as long as they have the proper permissions on the object.

Now let's step through the actual code that makes up these different menu items and show you how to use the ADSI object library with an Exchange Server directory.

Logging On to ADSI

The most common operation in the code for the menu items is the object binding code for ADSI. This binding code is dispersed throughout all the code modules in the application, rather than being centralized and performed only once, to make it easier for you to browse the code and understand exactly what is happening.

To bind successfully to an object in the Exchange Server directory using ADSI, you must use the OpenDSObject method after using the GetObject method to set an object variable to the ADSI library. The OpenDSObject method takes four parameters:

  • AdsPath. The path of the object you want to bind to. We saw how to create this path earlier in the chapter.
  • The Windows NT user name. Used to attempt authentication against the directory service.
  • The password for the Windows NT user name you specify.
  • A flag that specifies the binding option to use. You can use two possible flags: &H00000001 specifies to use secure authentication, and &H00000010 specifies to use encryption.

Depending on the provider used, these flags specifying the binding option might or might not be supported. On the LDAP provider, if you set both flags and pass in a user name and a password, ADSI will perform a simple bind over Secure Sockets Layer (SSL) sessions, which is a secure authentication over a secure channel. The sample application does not use either flag, so a 0 is passed in as the value for the final parameter to indicate that no encryption and no secure authentication should be used.

The following code example shows how to set an object variable to the LDAP provider and logon using the OpenDSObject method:

 Set oIADs = GetObject("LDAP:") oIADs.OpenDSObject(AdsPath, UserName, Password, 0) 

Creating a Mailbox

Using ADSI, you can create mailboxes easily in the Exchange Server directory, but they are not fully functional. ADSI does not provide a way for you to specify a Windows NT account as the primary owner of the mailbox, nor does it allow you to change the permissions on the mailbox so that the primary owner has permission to open it. You must perform these operations by using a separate program or the Exchange Administrator program. To specify a Windows NT account and to change user permissions on the mailbox in the sample application, I used a DLL named AcctCrt.DLL. This COM component is discussed in detail in Chapter 15.

Figure 14-5 shows the interface in the ADSI application that prompts the user for information about the mailbox she wants to create. This information is needed by the ADSI code to set specific properties in the Exchange Server directory. The application also asks for Windows NT account information so that a corresponding Windows NT user account can be created and identified as the primary account for the Exchange Server mailbox. Be sure to enter information in all text boxes; otherwise, an error will be displayed.

click to view at full size.

Figure 14-5 The page where the user can enter information about the mailbox the user wants to create using ADSI.

After the mailbox information is submitted, the ASP page called by the application sets a reference to the ADSI library. The ASP page also retrieves the Recipients container, where it will create the mailbox and the private mailbox store so that it can parse out the correct domain name for the user's SMTP address. The application creates proxy addresses for the user just in case the Exchange Server has a Lotus cc:Mail or Microsoft Mail connector installed. The application also sets other properties as shown in this code:

 <% bstrAT = Request.ServerVariables("AUTH_TYPE") If InStr(1, "_BasicNTLM", bstrAT, vbTextCompare) < 2 Then     Response.Buffer = TRUE     Response.Status = ("401 Unauthorized")     Response.AddHeader "WWW.Authenticate", "Basic"     Response.End end if dim arrOtherAddresses(1) 'Make sure to set error-checking on error resume next err.clear 'Retrieve the items from the previous form fn = Session("FN") ln = Session("LN") dn = Session("DN") al = Session("AL") dir = Session("DIR") NTDomain = Session("NTDomain") NTDescrip = Session("NTDescrip") NTPassword = Session("NTPassword") 'Create the Windows NT Account. 'Use the new AcctCrt component. set oNTContainer = CreateObject("MSExchange.AcctMgmt") oNTContainer.NtAccountCreate NTDomain, al, NTPassword, "", "" 'Get the SID and descriptor call oNTContainer.GetSidFromName(NTDomain, al, SecurityID) call oNTContainer.GenerateSecDescriptor(NTDomain, al, _      SecurityDescriptor) 'Create the Exchange Server mailbox 'Get a reference to the ADSI library Set oIADS = GetObject("LDAP:") 'Query to the Exchange Server bstr1 = "LDAP://" + Session("Server") + "/cn=" + Session("CN") + _     ",ou=" + Session("OU") + ",o=" + Session("O") bstr2 = Session("bstr2") bstr3 = Session("bstr3") 'Query to the Priv MDB on the Exchange Server bstrMDB = "LDAP://" + Session("Server") + _     "/cn=Microsoft Private MDB,cn=" + Session("Server") + _     ",cn=Servers ,cn=Configuration,ou=" + Session("OU") + ",o=" + _     Session("O") Set oContainer = oIADS.OpenDSObject(bstr1, bstr2, bstr3, 0) Set oMDB = oIADS.OpenDSObject(bstrMDB, bstr2, bstr3, 0) 'Create a new mailbox - class = organizationalPerson - with the  'correct directory name Set oIADS = oContainer.Create("organizationalPerson", "cn=" + _     CStr(dir)) oIADS.Put "NT-Security-Descriptor", (SecurityDescriptor) oIADS.Put "Assoc-NT-Account", (SecurityID) 'Retrieve the information from the Private MDB oMDB.GetInfo 'Retrieve the SMTP address for the PRIV MDB so that it can be parsed 'for the domain name strSMTPAddr = oMDB.Get("mail") 'Get up to the @ sign Pos = InStr(strSMTPAddr, "@") 'Parse out the domain name SMTPExt = Mid(strSMTPAddr, Pos, Len(strSMTPAddr)) strUserSMTPAddr = replace(al, " ", "") + SMTPExt 'Create the DN for the MTA of the user strDNMTA = "cn=Microsoft MTA,cn=" + Session("Server") + _     ",cn=Servers,cn=Configuration,ou=" + Session("OU") + ",o=" + _     Session("O") 'Set the array of other addresses such as CCMAIL, MSMAIL,  'Profs, etc. arrOtherAddresses(0) = "MS$" + Session("O") + "/" + _     Session("OU") + "/" + al arrOtherAddresses(1) = "CCMAIL$" + al + " at " + Session("OU") 'arrOtherAddresses(2) = "Your other addresses" 'Use the Put command to have ADSI write all of these values to  'the new mailbox. 'mailPreferenceOption must always be 0. oIADS.Put "mailPreferenceOption", 0 oIADS.Put "givenName", CStr(fn) oIADS.Put "sn", CStr(ln) oIADS.Put "cn", CStr(dn) oIADS.Put "uid", CStr(al) oIADS.Put "Home-MTA", CStr(strDNMTA) oIADS.Put "Home-MDB", "cn=Microsoft Private MDB,cn=" + _     Session("Server") + ",cn=Servers,cn=Configuration,ou=" +  oIADS.Put "mail", CStr(strUserSMTPAddr) oIADS.Put "MAPI-Recipient", True oIADS.Put "MDB-Use-Defaults", True oIADS.PutEx 2, "otherMailbox", (arrOtherAddresses) oIADS.Put "rfc822Mailbox", CStr(strUserSMTPAddr) oIADS.Put "textEncodedORaddress", CStr("c=US;a= ;p=" + _     Session("O") + ";o=" + Session("OU") + ";s=" + ln + ";g=" + _     fn + ";") oIADS.SetInfo if err.number = 0 then     'Success! %> <SCRIPT LANGUAGE="JavaScript">     alert("Successfully created mailbox and account!          Please click OK to continue.");     window.location="menu.asp"; </SCRIPT> <% else     'Failure! %> <SCRIPT LANGUAGE="JavaScript">     alert("Error! Error Number: <%=err.number %> Description:          <%=err.Description%>");     window.location="menu.asp"; </SCRIPT> <% end if %> 

As you can see in the code, the main properties set on the mailbox include givenName (First name), sn (Last Name), cn (Display Name), uid (Alias Name), Home-MTA, Home-MDB, mail (SMTP address), MAPI-Recipient, MDB-Use-Defaults, otherMailbox (other addresses for the mailbox such as CCMAIL and MSMAIL), rfc822Mailbox (SMTP address), and textEncodedORaddress (X.400 Address).

The example shows how to use the ADSI method PutEx to enter a multivalue property into the Exchange Server directory. To create the value for a multivalue property, you must use an array in VBScript. When passing this array as an argument to the PutEx call, you must place parentheses around the array to de-reference it. Recall that the Put and PutEx methods will modify the copy of the attributes in the property cache but not in the actual directory service. For this reason, the last statement in the code calls SetInfo to take all the changes in the cache and commit them to the directory service.

Querying for Information from an Existing Mailbox

The ADSI application also shows you how to query for information from an existing Exchange Server mailbox. The user interface, shown in Figure 14-6, allows you to type in the first name of the user to find the mailbox.

click to view at full size.

Figure 14-6 The page allows you to type the first name of the user in the directory to locate the mailbox.

After the user types in a name, the application uses ADO to query the directory service using LDAP. You might be wondering why ADO is used rather than the OpenDSObject method we saw in the code for creating a mailbox. The reason is that to use the OpenDSObject method, the user must know the exact name of the desired object in the directory. ADO is more forgiving. When the user is looking for an existing mailbox, the user is not typing in the exact name of the user he is looking for but rather some portion of the first name. Also, since many times users do not know the alias name of users they are querying, forcing users to type in aliases does not make sense. The code to create the ADO object and perform the query is shown here:

 bstrSearchCriteria = Request.Form("UserName") bstrServer = Session("Server") ' Create an ADO object Set ADOconn = CreateObject("ADODB.Connection") If Err.Number = 0 Then     ADOconn.Provider = "ADSDSOObject"     ADOconn.Open "ADs Provider"     'Create a query using ADO to find all users across all containers     bstrADOQueryString = "<LDAP://" + bstrServer + _         ">;(&(objectClass=organizationalPerson)(cn=" + _         bstrSearchCriteria + "*));cn,adspath;subtree"     Set objRS = ADOconn.Execute(bstrADOQueryString)     If Err.Number = 0 Then         If objRS.RecordCount > 0 Then %>             <p>Please select one of the following names from the              list of names.</p>             <p><em><strong>Returned Names:</strong></em></p>             <SELECT NAME='MailboxPath'>             <%             ' Builds the select control of the queried records             While Not objRS.EOF                 bstrSelectStatement = bstrSelectStatement & _                     "<OPTION VALUE='" & objRS.Fields(iCN).Value & _                     "'>" & objRS.Fields(iADSPATH)                 objRS.MoveNext             Wend             Response.Write bstrSelectStatement & "</SELECT>"         Else %>             <B><I>No entries match your search criteria.               Try again using a different value.</I></B>         <%         End If     Else         If Hex(Err.Number) = 80070044 Then             Response.Write "<FONT FACE='Arial, Helvetica' " + _                 "SIZE=2>Error " + Hex(Err.Number) + _                 ":  Too many entries match your search " + _                 "criteria!</FONT>"             Err.Clear         Else         %>             <SCRIPT LANGUAGE="JavaScript">             alert("Error Number: <%=Hex(Err.Number)%> \n                 Error Description: <%=Err.Description%>")             history.back()             </SCRIPT>             <%             Err.Clear         End If     End If Else %>     <SCRIPT LANGUAGE="JavaScript">     alert("Error Number: <%=Hex(Err.Number)%> \nError Description:          <%=Err.Description%>")     history.back()     </SCRIPT> <%     Err.Clear End If %> 

This code creates an ADO Connection object and sets the Provider property to ADSDSOObject, which specifies the LDAP provider for ADSI. You can specify any string for the connection string argument to the Open method of the ADO Connection object. In this case, the application specifies ADs Provider as the argument. The code then creates an LDAP query, which consists of four elements separated by semicolons. This is the format:

 <LDAP://server/adsidn>;ldapfilter;attributescsv;scope. 

The server argument specifies the name or the IP address of the server where the directory is hosted. The adsidn argument specifies the distinguished name in the directory where we want to start our query. (The distinguished path is discussed in Chapter 11.) You should pass in a correctly formed path, which we saw how to create earlier in the chapter. The filter parameter specifies the LDAP filter string to use. In this case, the LDAP filter states that the object class must be organizationalPerson and the name of the object must match the letters typed in by the user. The next argument, attributescsv, is a list of attribute names, separated by commas, that you want returned for each row in the recordset. In our example application, we want the name of the person and the AdsPath to the object that corresponds to that person returned so that we can place this information in the HTML form, as shown in Figure 14-7. The final argument, scope, informs the directory service how deeply in the hierarchy to search for the information being queried. The scope argument can be one of three values: base, onelevel, or subtree. Since we want to query for all mailboxes that match our specified criteria across all recipient containers in the directory, subtree is specified for this argument. The subtree argument causes the directory service to search for the information in every subtree under the starting object. Base searches only the currently specified object, and onelevel searches one level below the current object in the hierarchy.

If the query successfully returns records that match the filter, the code uses the standard ADO methods to scroll through the recordset and place the records in the HTML form.

click to view at full size.

Figure 14-7 After performing the query, the HTML form is populated with the corresponding recordsets so that a user can pick the person she is interested in finding more information about.

After the user selects the name of the person she wants to find more information about in the HTML form, the application opens the directory object for this person and retrieves information such as the address, phone number, manager, and direct reports. This information is then represented using a DHTML tabbed box in the browser, as shown in Figure 14-8.

click to view at full size.

Figure 14-8 The tabbed dialog box that shows the directory information for a specific user.

The next section of code retrieves the user information from the directory. I intentionally left out some of the DHTML code from the listing to highlight how ADSI is used in the code. Also, only a portion of the ADSI code is listed below because the structure of the code throughout this part of the application is very similar. Only the specific properties retrieved from the directory using ADSI are different. The full code is included on the companion CD.

 On Error Resume Next if Request.QueryString("Path") = "" then     bstrMailboxPath = Request.Form("MailboxPath") else     bstrMailboxPath = Request.Querystring("Path") end if bstrServer = Session("Server") Set objIADs = GetObject(bstrMailboxPath) strCustomAttributes = "LDAP://" & Session("Server") & _     "/cn=Attribnum" & ",cn=" & "Microsoft DMD" & ",ou=" & _     Session("ou") & ",o=" & Session("o") Function GetAttribName(AttribName)     strADsPath = Replace(strCustomAttributes,"Attribnum", _         AttribName,1,1)     set objAttributeName = GetObject(strADsPath)     strAttributeName = objAttributeName.Get("Admin-Display-Name")     GetAttribName = strAttributeName & ":" end Function ... <TR> <TD VALIGN=MIDDLE ALIGN=RIGHT> <FONT FACE="Arial, Helvetica" SIZE=2>First Name:</TD> <TD VALIGN=TOP><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("givenName"))%></B></FONT></TD> <TD VALIGN=MIDDLE ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Initials:</TD> <TD VALIGN=TOP><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("initials"))%></B></FONT></TD> <TD VALIGN=MIDDLE ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Last Name:</TD> <TD VALIGN=TOP><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("sn"))%></B></FONT></TD> </TR> <TR> <TD VALIGN=MIDDLE ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Display Name:</TD> <TD VALIGN=TOP><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("cn"))%></B></FONT></TD> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD VALIGN=MIDDLE ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Alias:</TD> <TD VALIGN=TOP><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("uid"))%></B></FONT></TD> </TR> <TR> <td width="100%" colspan="10">&nbsp;<hr> </TD> </TR> <TR> <TD VALIGN=TOP ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Address:</FONT></TD> <TD VALIGN=TOP><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("postalAddress"))%></B> </FONT></TD> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Title:</FONT></TD> <TD ALIGN=LEFT><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("title"))%></B></FONT></TD> </TR> <TR> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Company:</FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Company"))%></B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> City:</FONT></TD> <TD VALIGN=TOP><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("l"))%></B></FONT></TD> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Department:</FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("department"))%></B></FONT></TD> </TR> <TR> <TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> State:</FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("st"))%></B></FONT></TD> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Office:</FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("physicalDeliveryOfficeName"))%> </B></FONT></TD> </TR> <TR> <TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Zip Code:</FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("postalCode"))%></B> </FONT></TD> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Assistant:</FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("secretary"))%></B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Country:</FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("co"))%></B></FONT></TD> <TD>&nbsp;</TD> <TD>&nbsp;</TD> <TD ALIGN=RIGHT><FONT FACE="Arial, Helvetica" SIZE=2> Phone:</FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2><B> <%=Server.HTMLEncode(objIADs.Get("telephoneNumber"))%> </B></FONT></TD> </TR> </TABLE> </DIV> <DIV CLASS=conts ID=t2Contents> <!--  Draw out the tab for Organization --> <Table width=600> <TR> <TD width=100% colspan="5"><img src="mailbox.jpg" align="middle"> &nbsp;<FONT FACE="Arial, Helvetica" SIZE=5> <B><%=Server.HTMLEncode(objIADs.Get("cn"))%></B></FONT></TD> </TR> <TR>&nbsp;</TR></TABLE> <Table border=0> <TR> <TD ALIGN=LEFT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> Manager Name:</FONT></TD> <TR>&nbsp;</TR> <%     strManager = objIADs.Get("manager")     strManagerPath = "LDAP://" & Session("Server") & "/" & strManager     set oIADsManager = GetObject(strManagerPath)     strManagercn = Server.HTMLEncode(oIADsManager.Get("cn")) %> <TR> <TD><FONT FACE="Arial, Helvetica" SIZE=2><B> <A Href='MBINFOTABS.ASP?Path=<%=strManagerPath%>'> <%=strManagercn%></a></B></FONT></TD> </TR> <TR><TD>&nbsp;</TD></TR> <TR><TD ALIGN=LEFT><FONT FACE="Arial, Helvetica" SIZE=2> Direct Reports:</FONT></TD></TR> <% err.clear     strReports = objIADs.GetEx("Reports")         for i = LBound(strReports) to UBound(strReports)             'Get each DS object to return the friendly name             strDirectPath = "LDAP://" & Session("Server") & _                 "/" & strReports(i)             set oIADsReports = GetObject(strDirectPath)             strReportscn = _                 Server.HTMLEncode(oIADsReports.Get("cn")) %>             <TR><TD><FONT FACE="Arial, Helvetica" SIZE=2>             <B><img src="mailboxs.jpg" ALIGN="Middle">&nbsp;             <A Href='MBINFOTABS.ASP?Path=<%=strDirectPath%>'>             <%=strReportscn%></a>             </B></TD></TR> <%         next %> </TR></TABLE> </DIV> <DIV CLASS=conts ID=t4Contents> <!--  Draw out the tab for Custom Attributes --> <Table width=600> <TR> <TD width=100% colspan="5"><img src="mailbox.jpg" align="middle"> &nbsp;<FONT FACE="Arial, Helvetica" SIZE=5> <B><%=Server.HTMLEncode(objIADs.Get("cn"))%></B></FONT></TD> </TR> <TR>&nbsp;</TR> </TABLE> <Table> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-1")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-1"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-2")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-2"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-3")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-3"))%></B> </FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-4")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-4"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-5")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2><B> <%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-5"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-6")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-6"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-7")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2><B> <%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-7"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-8")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2><B> <%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-8"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-9")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-9"))%> </B></FONT></TD> </TR> </TABLE> </FORM> </DIV> 

The mailbox that the user wants to query is passed to the ASP page. Using the GetObject method, the code opens that mailbox in the Exchange Server directory and sets an object variable, objIADs, to that mailbox. Throughout much of the remaining code, the Get method of the objIADs object is used to retrieve specific attributes on the mailbox.

The most interesting pieces of code besides the code for retrieving attributes include those that retrieve the user's manager and direct reports from the directory. In the application, the manager's name is displayed as a hyperlink on the Organization tab so that users can quickly look up the manager's directory information. The direct reports of the current user are also displayed as hyperlinks on the Organization tab so that users can look at the direct report's directory information as well. Figure 14-9 shows a sample of these hyperlinks.

click to view at full size.

Figure 14-9 The Organization tab for a queried mailbox displays the manger and direct reports as hyperlinks.

The following code implements the hyperlink functionality:

 <Table border=0> <TR> <TD ALIGN=LEFT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> Manager Name:</FONT></TD> <TR>&nbsp;</TR> <%     strManager = objIADs.Get("manager")     strManagerPath = "LDAP://" & Session("Server") & "/" & strManager     set oIADsManager = GetObject(strManagerPath)     strManagercn = Server.HTMLEncode(oIADsManager.Get("cn")) %>     <TR> <TD><FONT FACE="Arial, Helvetica" SIZE=2><B> <A Href='MBINFOTABS.ASP?Path=<%=strManagerPath%>'> <%=strManagercn%></a></B></FONT></TD> </TR> <TR><TD>&nbsp;</TD></TR> <TR><TD ALIGN=LEFT><FONT FACE="Arial, Helvetica" SIZE=2> Direct Reports:</FONT></TD></TR> <% err.clear strReports = objIADs.GetEx("Reports") for i = LBound(strReports) to UBound(strReports)     'Get each DS object to return the friendly name     strDirectPath = "LDAP://" & Session("Server") & "/" & _         strReports(i)     set oIADsReports = GetObject(strDirectPath)     strReportscn = Server.HTMLEncode(oIADsReports.Get("cn")) %>     <TR><TD><FONT FACE="Arial, Helvetica" SIZE=2>     <B><img src="mailboxs.jpg" ALIGN="Middle">&nbsp;     <A Href='MBINFOTABS.ASP?Path=<%=strDirectPath%>'>     <%=strReportscn%></a>     </B></FONT></TD></TR> <%     next %> </TR></TABLE> 

When you retrieve the manager property from the Exchange Server directory, the directory returns the distinguished name of the manager. To retrieve the display name of the manager, the code uses the distinguished name to create a full AdsPath to the directory object that corresponds to the manager. Then the code opens that object and retrieves the display name of the manager.

To retrieve the direct reports, the code uses the GetEx method in ADSI. (Recall that the reports attribute is a multivalued property. You must use GetEx when retrieving multivalued properties from the Exchange Server directory.) The GetEx code returns an array of distinguished names for all direct reports of the current user. The code scrolls through each direct report in the array, and it displays as a hyperlink an image and the full name of each direct report.

The next code snippet includes some interesting code that retrieves the custom attribute names and the values for these custom attributes. The Exchange Server directory contains 15 customizable attributes that developers or administrators can use to specify custom properties for each entry in the directory. Because you can customize the attribute names so that they correspond to the value types you store in the attribute, such as cost center or social security number, the application queries the Exchange Server directory for the names of the custom attributes. The application also queries the directory for the actual values in the attributes. All of this functionality is implemented in the following section of code:

 strCustomAttributes = "LDAP://" & Session("Server") & _     "/cn=Attribnum" & ",cn=" & "Microsoft DMD" & ",ou=" & _     Session("ou") & ",o=" & Session("o") Function GetAttribName(AttribName)     strADsPath = Replace(strCustomAttributes,"Attribnum", _         AttribName,1,1)     set objAttributeName = GetObject(strADsPath)     strAttributeName = objAttributeName.Get("Admin-Display-Name")     GetAttribName = strAttributeName & ":" end Function ... <Table> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-1")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-1"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-2")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-2"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-3")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-3"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-4")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-4"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-5")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-5"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-6")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-6"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-7")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-7"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-8")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-8"))%> </B></FONT></TD> </TR> <TR><TD ALIGN=RIGHT NoWrap><FONT FACE="Arial, Helvetica" SIZE=2> <%=GetAttribName("Extension-Attribute-9")%></FONT></TD> <TD><FONT FACE="Arial, Helvetica" SIZE=2> <B><%=Server.HTMLEncode(objIADs.Get("Extension-Attribute-9"))%> </B></FONT></TD> </TR> </TABLE> 

Notice that in the strCustomAttributes string, the container Microsoft DMD is specified. This container corresponds to the actual schema definitions for the Exchange Server directory. To retrieve the names of any custom attributes, we must query the schema. To make the querying easier, I created a function that takes a string that specifies the name of the custom attribute you want to query. The function in turn grabs that attribute in the schema and figures out the corresponding custom name of the attribute—for example, cost center. The code then uses the standard Get method on the user's mailbox to retrieve the attribute value for that particular user and attribute, as shown in Figure 14-10.

click to view at full size.

Figure 14-10 The Custom Attributes tab that shows the custom attributes for the queried mailbox and the custom names of those attributes from the Exchange Server schema.

Creating a Custom Recipient

The code for creating a custom recipient in the Exchange Server directory is similar to the code for creating a mailbox, as you would expect. The main differences are these:

  • You must specify remote-address as the object class for a custom recipient rather than organizationalPerson, which is the object class for a mailbox.
  • You need to set different properties when creating a custom recipient. For example, you must set the target-address property of the custom recipient, which specifies the actual address of the recipient.

The following code creates a custom recipient using ADSI:

 Dim arrOtherAddresses(1) on error resume next err.clear smtp = Request.Form("SMTP") fn = Request.Form("FN") ln = Request.Form("LN") dn = Request.Form("DN") al = Request.Form("AL") dir = Request.Form("DIR") Set oIADs = GetObject("LDAP:") bstr1 = "LDAP://" + Session("Server") + "/cn=" + Session("CN") + _     ",ou=" + Session("OU") + ",o=" + Session("O") bstr2 = Session("bstr2") bstr3 = Session("bstr3") Set oContainer = oIADs.OpenDSObject(bstr1, bstr2, bstr3, 0) Set oIADs = oContainer.Create("remote-address", "cn=" + CStr(dir)) arrOtherAddresses(0) = "MS$" + Session("O") + "/" + _     Session("OU") + "/" + al arrOtherAddresses(1) = "CCMAIL$" + al + " at " + Session("OU") oIADs.Put "target-address", "SMTP:" + CStr(smtp) oIADs.Put "givenName", CStr(fn) oIADs.Put "sn", CStr(ln) oIADs.Put "cn", CStr(dn) oIADs.Put "uid", CStr(al) oIADs.Put "MAPI-Recipient", False oIADs.Put "mail", CStr(smtp) oIADs.PutEx 2, "otherMailbox", (arrOtherAddresses) oIADs.Put "rfc822Mailbox", CStr(smtp) oIADs.Put "textEncodedORaddress", CStr("c=US;a= ;p=" + _     Session("O") + ";o=" + Session("OU") + ";s=" + ln + _     ";g=" + fn + ";") oIADs.SetInfo 

Creating a Distribution List

Creating a distribution list, like creating a custom recipient, is again very similar to creating a mailbox. The object class for a distribution list is groupOfNames, and the properties you need to set for the distribution list are a little different from the properties you set for a mailbox. For example, for a distribution list, you can set the report-to-owner and the report-to-originator properties, which specify whether reports should be sent to the distribution list owner or to the message originator, respectively. You can also set the distribution list owner property, as shown in the next snippet of code, by placing the distinguished name of a user into the owner property. This code creates a distribution list:

 <% dim arrOtherAddress(1) on error resume next err.clear cn = Request.Form("cn") uid = Request.Form("uid") owner = Request.Form("owner") Set oIADs = GetObject("LDAP:") bstr1 = "LDAP://" + Session("Server") + "/cn=" + Session("CN") + _     ",ou=" + Session("OU") + ",o=" + Session("O") bstr2 = "cn=" + Session("UserName") + ", cn=" + Session("Domain") bstr3 = Session("Password") bstrMDB = "LDAP://" + Session("Server") + _     "/cn=Microsoft Private MDB,cn=" + Session("Server") + _     ",cn=Servers ,cn=Configuration,ou=" + Session("OU") + _     ",o=" + Session("O") bstrOwner = "LDAP://" + Session("Server") + "/cn=" + owner + _     ",cn=" + Session("CN") + ",ou=" + Session("OU") + _     ",o=" + Session("O") Set oContainer = oIADs.OpenDSObject(bstr1, bstr2, bstr3, 0) Set oObject = oIADs.OpenDSObject(bstrMDB, bstr2, bstr3, 0) set oOwner = oIADs.OpenDSObject(bstrOwner,bstr2,bstr3,0) Set oIADs = oContainer.Create("groupOfNames", "cn=" + uid) oIADs.Put "cn", Cstr(cn) oIADs.Put "uid", CStr(uid) oIADs.Put "owner", oOwner.distinguishedName oObject.GetInfo Mail = oObject.Get("mail") Pos = InStr(Mail, "@") SMTPExt = Mid(Mail, Pos, Len(Mail)) iaddr = replace(uid, " ", "") + SMTPExt arrOtherAddress(0) = CStr("MS$" + Session("O") + "/" + _     Session("OU") + "/" + uid) arrOtherAddress(1) = Cstr("CCMAIL$" + uid + " at " + _     Session("OU")) oIADs.Put "distinguishedName", CStr("cn=" + uid + ",cn=" + _     Session("CN") + ",ou=" + Session("OU") + ",o=" + Session("O")) oIADs.Put "mail", CStr(iaddr) oIADs.PutEx 2, "otherMailbox", (arrOtherAddress) oIADs.Put "Report-To-Originator", True oIADs.Put "Report-to-Owner", False oIADs.Put "Replication-Sensitivity", CInt(20) oIADs.Put "rfc822Mailbox", CStr(iaddr) oIADs.Put "textEncodedORaddress", CStr("c=US;a= ;p=" + _     Session("O") + ";o=" + Session("OU") + ";s=" + uid + ";") oIADs.SetInfo if err.number = 0 then     'Success! %>     <SCRIPT LANGUAGE="JavaScript">         alert("Distribution List successfully created.          Please click OK to continue.");         window.location="menu.asp";     </SCRIPT> <% else     'Failure! %>     <SCRIPT LANGUAGE="JavaScript">         alert("Error! Error Number: <%=err.number %>          Description: <%=err.Description%>");         window.location="menu.asp";     </SCRIPT> <% end if %> 

Adding and Removing Users from a Distribution List

ADSI provides another interface that you can take advantage of when working with directory objects that manage group memberships such as a distribution list: the IADsGroup interface. It provides methods, such as Add and Remove, that make it easy to add and remove members from the group. All you need to specify to these methods is the AdsPath that corresponds to the object you will either add or remove. To remove a user from a distribution list, you would just replace the Add method call with the Remove method.

This interface also provides a Members method that returns a collection of the current members of the group. The following code checks to see whether a user is already a member of a distribution list and, if the user is not, the code adds the user to the list:

 <% Set oIADs = GetObject("LDAP:") bstr1 = Session("strDLName") bstr2 = Session("bstr2") bstr3 = Session("bstr3") 'Open the Exchange Server DS object Set objDL = oIADs.OpenDSObject(bstr1, bstr2, bstr3, 0) strAlias = Request.Form("USERSELECT") bstr1 = strAlias bstr2 = Session("bstr2") bstr3 = Session("bstr3") 'Open the object in the Exchange Server DS that corresponds to  'the user set objUser = oIADs.OpenDSObject(bstr1, bstr2, bstr3, 0) booluserdoesnotexist=true for each item in objDL.Members     if item.ADSPath = strAlias then         booluserdoesnotexist = false     end if next if booluserdoesnotexist then     'User does not exist in the DL already, so add the user     objDL.Add objUser.ADSPath     if err.number = 0 then %>         <SCRIPT LANGUAGE="JavaScript">             alert("Successfully added user to DL.                  Please click OK to continue.");             window.location="menu.asp";         </SCRIPT> <%     else         'Failure! %>         <SCRIPT LANGUAGE="JavaScript">             alert("Error! Error Number: <%=err.number %>                  Description: <%=err.Description%>");             window.location="menu.asp";         </SCRIPT> <%     end if else     'User does exist! %>     <SCRIPT LANGUAGE="JavaScript">         alert("User already is a member of this DL.               Please click OK to continue.");         window.location="menu.asp";     </SCRIPT> <% end if %> 

Displaying the Users in a Distribution List

The sample application allows you to display the users contained in a distribution list in an HTML table, as shown in Figure 14-11. This table is generated by using a For…Each construct to scroll through the collection returned by the IADsGroup Members method. After retrieving the object that corresponds to each member, the code checks the object class and displays the correct identifier for each member, such as mailbox, distribution list, or custom recipient. Remember that distribution lists can hold different types of objects. The code that displays users in a distribution list is shown here:

 <HTML> <HEAD> <TITLE>Display users in DL</TITLE> </HEAD> <BODY> <h1>The members of this DL are:</font></h1> <hr> <form METHOD="POST" NAME="INFO" ACTION=""> <input TYPE="button" VALUE="Back to Main Menu"     OnClick='window.location="menu.asp";'>     <input TYPE="button" VALUE="Select different container"      OnClick='window.location="logon.asp?diffcont=1";'> </FORM> <P> <TABLE BORDER=1 bgcolor="#79AA86"> <% dim oIADs dim MyContainer dim objRecipients dim item on error resume next err.clear strDLName = Request.Form ("DLSELECT") Set oIADs = GetObject("LDAP:") bstr1 = strDLName bstr2 = Session("bstr2") bstr3 = Session("bstr3") Set objDL = oIADs.OpenDSObject(bstr1, bstr2, bstr3, 0) Response.Write "<TR><TD><B>Class</TD><TD><B>Display Name</TD> <TD><B>Alias</TD><TD><B>Directory Name</TD></TR>" for each item in objDL.Members     set objitem =  oIADs.OpenDSObject(item.ADSPath, bstr2, bstr3, 0)     select case item.class         case "organizationalPerson"             Response.Write "<TD>MailBox</TD><TD>" & _             objitem.get("cn") & "</TD><TD>" &objitem.get("uid") & _             "</TD><TD>" & item.name & "</TD></TR>"         case "Remote-Address"             Response.Write "<TD>Custom Recipient</TD><TD>" & _             objitem.get("cn") & "</TD><TD>" & objitem.get("uid") & _             "</TD><TD>" & item.name & "</TD></TR>"         case "groupOfNames"             Response.Write "<TD>Distribution List</TD><TD>" & _             objitem.get("cn") & "</TD><TD>" & objitem.get("uid") & _             "</TD><TD>" & item.name & "</TD></TR>"         case else             Response.Write "<TD>" & item.class & "</TD><TD>" & _             objitem.get("cn") & "</TD><TD>" & objitem.get("uid") & _             "</TD><TD>" & item.name & "</TD></TR>"     end select next %> </TABLE> </FONT> 

click to view at full size.

Figure 14-11 An HTML table of the users in a specific distribution list. The table is generated by parsing the return value of the Members method of the IADsGroup interface.

Creating a Recipients Container

The code that creates a Recipients container is probably the easiest to write in ADSI because you don't need to set many properties on it. Just remember to specify Container as the object class when creating the new Recipients container. The only gotcha when creating a Recipients container is that if you want the container to appear in the address book, you must set the Container-Info attribute to _2147483647 or &H80000001. The following code creates a Recipients container based on the values specified by the user:

 <% on error resume next err.clear strDisplayName = Request.Form("display") strDirectoryName = Request.Form("dir") Set oIADs = GetObject("LDAP:") bstr1 = "LDAP://" + Session("Server") + "/ou=" + Session("OU") + _     ",o=" + Session("O") bstr2 = Session("bstr2") bstr3 = Session("bstr3") Set oContainer = oIADs.OpenDSObject(bstr1, bstr2, bstr3, 0) Set oIADs = oContainer.Create("Container", "cn=" + strDirectoryName) oIADs.Put "Container-Info", -2147483647 oIADs.Put "Admin-Display-Name", Cstr(strDisplayName) oIADs.Put "rdn", CStr(strDirectoryName) oIADs.SetInfo if err.number = 0 then     'Success! %>     <SCRIPT LANGUAGE="JavaScript">         alert("Recipients Container successfully created.              Please click OK to continue.");         window.location="menu.asp";     </SCRIPT> <% else     'Failure! %>     <SCRIPT LANGUAGE="JavaScript">         alert("Error! Error Number: <%=err.number %> Description:              <%=err.Description%>");         window.location="menu.asp";     </SCRIPT> <% end if %> 

Displaying the Objects in a Recipients Container

The final code we'll look at in this chapter is similar to the code that displays the members of a distribution list. This code, however, displays the objects contained in a specific Recipients container in the directory. The first part of the code displays the list of available Recipients containers in the directory by scrolling through the available objects below the OU, or Exchange Server site, and then parses out only the objects whose class name is Container. Since the Configuration portion of Exchange Server, which contains settings for connectors, protocol settings, and monitor settings, also has an object class of Container, and you do not want users trying to display all the objects in the Configuration container, the code skips this Configuration container. The code then displays all the remaining Recipients containers so that the user can select the container whose contents they want to display.

 on error resume next err.clear Set oIADs = GetObject("LDAP:") bstr1 = "LDAP://" + Session("Server") + "/ou=" + Session("OU") + _     ",o=" + Session("O") bstr2 = Session("bstr2") bstr3 = Session("bstr3") Set oRecips = oIADs.OpenDSObject(bstr1, bstr2, bstr3, 0) for each child in oRecips     select case child.class         case "Container"             'Block out the Configuration container             if instr(child.name,"Configuration") = 0 then                 Response.Write "<OPTION VALUE='" & child.Name & _                     "'>" & Replace(child.name,"cn=", "")             end if     end select next 

Next the code scrolls through all the objects in the selected container and displays the class, display name, alias, and directory name of the object by using a For...Each construct. The result of this code is shown in Figure 14-12.

 <% on error resume next err.clear Set oIADs = GetObject("LDAP:") bstr1 = "LDAP://" + Session("Server") + "/" + Request.Form("cn") + _     ",ou=" + Session("OU") + ",o=" + Session("O") bstr2 = Session("bstr2") bstr3 = Session("bstr3") Set oRecipObjects = oIADs.OpenDSObject(bstr1, bstr2, bstr3, 0) Response.Write "<TR><TD><B>Type</TD><TD><B>Display Name</TD> <TD><B>Alias</TD><TD><B>Directory Name</TD></TR>" for each item in oRecipObjects     set objitem =  oIADs.OpenDSObject(item.ADSPath, bstr2, bstr3, 0)     select case item.class         case "organizationalPerson"             Response.Write "<TD>MailBox</TD><TD>" + _             objitem.get("cn") + "</TD><TD>" + objitem.get("uid") + _             "</TD><TD>" + item.name + "</TD></TR>"         case "Remote-Address"             Response.Write "<TD>Custom Recipient</TD><TD>" + _             objitem.get("cn") + "</TD><TD>" + objitem.get("uid") + _             "</TD><TD>" + item.name + "</TD></TR>"         case "groupOfNames"             Response.Write "<TD>Distribution List</TD><TD>" + _             objitem.get("cn") + "</TD><TD>" + objitem.get("uid") + _             "</TD><TD>" + item.name + "</TD></TR>"         case "Container"             Response.Write "<TD>Container</TD><TD>" + _             objitem.get("rdn") + "</TD><TD>" + + "</TD><TD>" + _             item.name + "</TD></TR>"         case else             Response.Write "<TD>" + item.class + "</TD><TD>" + _             objitem.get("cn") + "</TD><TD>" + objitem.get("uid") + _             "</TD><TD>" + item.name + "</TD></TR>"     end select next %> 

Raising the Number of Results Returned for LDAP Queries

By default, Exchange Server will return only 100 results, so you might want to raise the number of results the Exchange Server returns for LDAP queries. To do this, launch the Exchange Administrator program, and under the Configuration object for your site, select the Protocols icon. Double-click the LDAP (Directory) Site Defaults icon in the right pane. In the displayed Properties dialog box, click on the Search tab. Increase the number in the text box named Maximum Number Of Search Results Returned to the number of results you want to return from an LDAP query. If you do not raise this number and your LDAP query has more than the default 100 results, Exchange Server will not return any results.

click to view at full size.

Figure 14-12 The HTML table, which is dynamically generated from the object in a Recipients Container.



Programming Microsoft Outlook and Microsoft Exchange
Programming Microsoft Outlook and Microsoft Exchange, Second Edition (DV-MPS Programming)
ISBN: 0735610193
EAN: 2147483647
Year: 1999
Pages: 101

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net