Microsoft Corporation
November 1997
Active Directory Services Interfaces (ADSI) makes it easy to create directory-enabled applications by using high-level tools such as the Microsoft® Visual Basic® programming system, Java®, C, or the Visual C++® development system without having to worry about the underlying differences between the different directory implementations or namespaces. This means that you will be able to build applications that give you a single point of access to multiple directories in your network environment, whether those directories are based on the Lightweight Directory Access Protocol (LDAP) service, the NetWare Directory Service (NDS), or Windows NT Directory Service (NTDS).
Microsoft Exchange 5.5 is a scalable, reliable, and secure messaging platform. Microsoft Exchange 5.5 directory service supports LDAP V3. You can use ADSI with its LDAP provider to manipulate any object in the Microsoft Exchange 5.5 directory. This capability, together with Collaboration Data Objects (CDO), allows Administrators and developers to write powerful collaborative applications or administration tools efficiently. Formerly known as Active Messaging, CDO provides the object interface for manipulating message and calendar objects as well as submission and retrieval of such objects.
This paper helps application developers to write directory-enabled applications using ADSI on top of the Exchange 5.5 directory service.
ADSI provides a Component Object Model (COM) interface to directory objects. ADSI is built on a provider-based model; the client interacts with the COM interfaces exposed by ADSI while the providers implement the mapping between the underlying directory system and the COM interfaces exposed by the ADSI client. An ADSI application that creates or modifies a user in an NDS directory can be used to create a user in an Exchange 5.5 directory. On the other hand, LDAP is an on-the-wire protocol for directory access. So an LDAP application is restricted to accessing directories that expose the LDAP protocol.
Given that ADSI is a set of COM objects, it can easily be used within Visual Basic or Java script to directory-enable your Web-based applications. It is somewhat harder to do that with a "C"-based LDAP API.
ActiveX® Data Objects (ADO) is used to perform searches within the directory and have the results presented in a tabular form. ADSI, on the other hand, is used to modify entries in the directory. Often you use ADO to search for one or more objects then iterate through the result set and modify the objects of interest. The use of ADSI and ADO is illustrated in the samples below.
In order to write applications using ADSI on the Exchange directory, you must have an understanding of the directory schema. The schema defines the available object classes in the directory, the relationship between the object classes, the attributes on each object class, and specific characteristics of the attributes and classes. The Exchange Administration program allows you to view the Exchange directory schema. To do this:
There are three properties that are significant in ADSI support:
The heuristic property can be interpreted as follows:
Bit 0 | 0: Replicate between sites 1: Do not replicate between sites |
Bit 1 | 0: Attribute is not visible through LDAP 1: Attribute is visible to anonymous and authenticated LDAP clients |
Bit 2 | 0: Attribute is not accessible by authenticated clients 1: Attribute is accessible to authenticated clients but not anonymous clients |
Bit 3 | 0: Attribute is not an operational attribute 1: Attribute is an operational attribute |
Bit 4 | 0: Attribute is not visible in Admin UI (Attributes page of “DS Site Configuration” object) 1: Attribute is visible in Admin UI (Attributes page of “DS Site Configuration” object) |
By taking note of heuristics, you can determine the visibility of particular attributes. For example, a heuristic value of 3 means the attribute is not replicated between sites and is visible by anonymous LDAP clients.
A heuristic value of 11 means the attribute is an operational attribute and is visible to authenticated LDAP clients.
Operational attributes (attributes with a heuristic bit 3 set) are not visible through ADSI even though it is possible to set their values. To get the value of an operational attribute, you must use an ADO query as described in the example below.
Caution Changing bit 0 of the heuristic property could cause directory replication to stop. You should not change this bit of the heuristic property of an attribute.
The ACL property determines what rights a user needs to modify the attribute. The ACL property value definitions are:
0: | Only the System can modify the attribute |
1: | Users with Modify Admin right can modify the attribute |
2: | Users with Modify User right can modify the attribute |
3: | Users with Modify permissions right can modify the attribute |
Description determines the LDAP name of the attribute or class.
Caution Changing the LDAP name causes interoperability problems.
The following section contains object classes commonly used as well as their most significant attributes. The columns in the tables below should be interpreted as follows:
LDAP Name: | Name of the attribute through LDAP (the Description of the attribute in the Exchange schema). |
Exchange Name: | The name of the attribute in the Exchange schema. |
Mandatory: | Whether the attribute is mandatory on the object or not. |
Heuristic: | The heuristic of the attribute as described above. |
ACL: | The access category of the attribute as described above. |
Syntax: | The syntax of the attribute.
|
The Mail-Recipient object class is exposed as the “person” object class through LDAP. This object class is inherited by all object classes to which mail can be sent—for example mailbox, custom-recipient, distribution-list, and public-folder.
It should be noted that this object class is abstract. Thus you cannot create an instance of this object class. It is defined only so that other object classes in the directory can inherit its attributes.
The following table describes the commonly used attributes on the person object class:
LDAP Name | Exchange Name | Mandatory | Heuristic | ACL | Syntax | Comment | ||
rdn | Common-Name | Y | 2 | 1 | String(Teletex) | Common Name (RDN of this object) | ||
cn | Display Name | N | 2 | 1 | String(Unicode) | The String displayed by the address book | ||
language | Language-ISO639 | N | 3 | 2 | String(Unicode) | ISO639 Language | ||
LabeledURI | LabeledURI | N | 5 | 2 | String(Unicode) | URL specifying default HTML Web page | ||
Voice-Mail-Recorded-Name | Voice-Mail-Recorded-Name | N | 13 | 2 | String(Octet) | The Voice Mail user's spoken name | ||
Voice-Mail-Password | Voice-Mail-Password | N | 13 | 2 | String(Unicode) | DTMF digits representing user account security code | ||
Voice-Mail-Greetings | Voice-Mail-Greetings | N | 13 | 2 | String(Unicode) | The Voice Mail user's recorded greeting(s) | ||
Voice-Mail-User-ID | Voice-Mail-User-ID | N | 13 | 2 | String(Unicode) | DTMF digits representing a user account (e.g. phone extension) | ||
MAPI-Recipient | MAPI-Recipient | N | 18 | 1 | Boolean | Indicates to a Gateway if it's a MAPI recipient (True=Yes, False=No) | ||
mail, rfc822Mailbox,OtherMailbox, textEncodedORAddress | Proxy-Addresses | N | 18 | 1 | String(Teletex) | The list of foreign mail system addresses for this recipient. This attribute is exposed as follows: Primary SMTP address - mail Primary X.400 address - textEncodedORAddress other addresses - otherMailbox | ||
name | Display-Name-Printable | N | 18 | 1 | String(Printable) | The Printable String version of the Display-Name. | ||
uid | Mail-nickname | N | 18 | 1 | String(Unicode) | Mail Nickname | ||
info | Comment | N | 18 | 2 | String(Unicode) | This recipient's comment in the Exchange address book. | ||
url | WWW-Home-Page | N | 18 | 2 | String(Unicode) | WWW Home page associated with this entry | ||
userCertificate | X509-Cert | N | 18 | 2 | String(Octet) | The X.509 v3 certificate(s) of the user | ||
Extension-Attribute-9 | Extension-Attribute-9 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-1 | Extension-Attribute-1 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-10 | Extension-Attribute-10 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-2 | Extension-Attribute-2 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-3 | Extension-Attribute-3 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-4 | Extension-Attribute-4 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-5 | Extension-Attribute-5 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-6 | Extension-Attribute-6 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-7 | Extension-Attribute-7 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-8 | Extension-Attribute-8 | N | 20 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-15 | Extension-Attribute-15 | N | 21 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-11 | Extension-Attribute-11 | N | 21 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-12 | Extension-Attribute-12 | N | 21 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-14 | Extension-Attribute-14 | N | 21 | 1 | String(Unicode) | General extension attribute for customer use | ||
Extension-Attribute-13 | Extension-Attribute-13 | N | 21 | 1 | String(Unicode) | General extension attribute for customer use |
The Mailbox object class is exposed as the “organizationalPerson” object class through LDAP. This object class represents an object that contains mail storage in the Microsoft Exchange system. One critical attribute on a Mailbox object is the Assoc-NT-Account, which contains the Security Identifier (SID) of the NT account that has access to the mailbox.
LDAP Name | Exchange Name | Mandatory | Heuristic | ACL | Syntax | Comment |
mailPreferenceOption | Delivery-Mechanism | Y | 4 | 1 | Integer | The mechanism by which this mailbox receives mail. This attribute should be set to 0. |
personalTitle | Personal-Title | N | 3 | 2 | String(Unicode) | Personal Title (Mr., Mrs., etc.) |
Assoc-NT-Account | Assoc-NT-Account | N | 12 | 1 | String(Octet) | The primary NT account associated with this Mailbox |
street | Street-Address | N | 12 | 1 | String(Unicode) | Physical street address |
generationQualifier | Generation-Qualifier | N | 13 | 1 | String(Unicode) | Generation Qualifier e.g. Sr., Jr., IV |
houseIdentifier | House-Identifier | N | 13 | 1 | String(Unicode) | Building within a location |
Company | Company | N | 18 | 1 | String(Unicode) | Company of the Mailbox Owner |
department | Department | N | 18 | 1 | String(Unicode) | The "Department" of this recipient. |
givenName | Given-Name | N | 18 | 1 | String(Unicode) | Specifies the first name (given name) of the Mailbox Owner |
internationalISDNNumber | International-ISDN-Number | N | 18 | 1 | String(Numeric) | ISDN Number associated with the Mailbox |
manager | Manager | N | 18 | 1 | Object(DS-DN) | The "Manager" of this recipient. |
physicalDeliveryOfficeName | Office | N | 18 | 1 | String(Unicode) | e.g. "1/1061" |
sn | Last Name | N | 18 | 1 | String(Unicode) | Specifies the last name (surname) of the Mailbox Owner |
st | State-Or-Province-Name | N | 18 | 1 | String(Unicode) | The State or Province the user is located in |
teletexTerminalIdentifier | Teletex-Terminal-Identifier | N | 18 | 1 | String(Octet) | |
title | Title | N | 18 | 1 | String(Unicode) | Business title of the Mailbox Owner |
x121Address | X121-Address | N | 18 | 1 | String(Numeric) | |
Telephone-Office2 | N | 18 | 2 | String(Unicode) | Office Phone Number (2) of the Mailbox Owner | |
co | Text-Country | N | 18 | 2 | String(Unicode) | The country the user is located in |
facsimileTelephoneNumber | Telephone-Fax | N | 18 | 2 | String(Unicode) | Fax Phone Number of the Mailbox Owner |
homephone | Home phone number | N | 18 | 2 | String(Unicode) | Home Phone Number of the Mailbox Owner |
initials | Initials | N | 18 | 2 | String(Unicode) | User's Initials |
l | City | N | 18 | 2 | String(Unicode) | The location/City of the user |
mobile | Mobile number | N | 18 | 2 | String(Unicode) | Cellular Phone Number of the Mailbox Owner |
pager | Pager number | N | 18 | 2 | String(Unicode) | Pager Phone Number of the Mailbox Owner |
postalAddress | Address | N | 18 | 2 | String(Unicode) | Street address of the Mailbox Owner |
postalCode | Postal code | N | 18 | 2 | String(Unicode) | Postal/Zip Code |
secretary | Assistant | N | 18 | 2 | String(Unicode) | Mailbox Assistant Display Name |
telephoneNumber | Phone number | N | 18 | 2 | String(Unicode) | Office Phone Number (1) of the Mailbox Owner |
telexNumber | Telex-Number | N | 18 | 2 | String(Octet) | |
employeeNumber | Employee-Number | N | 21 | 1 | String(Unicode) | Employee Number |
employeeType | Employee-Type | N | 21 | 1 | String(Unicode) | Type of Employee |
homeFax | Telephone-Home-Fax | N | 21 | 2 | String(Unicode) | Home Fax Number |
homePostalAddress | Address-Home | N | 21 | 2 | String(Unicode) | Home Address |
personalMobile | Telephone-Personal-Mobile | N | 21 | 2 | String(Unicode) | Personal Mobile Number |
personalPager | Telephone-Personal-Pager | N | 21 | 2 | String(Unicode) | Personal Pager Number |
The Custom-Recipient object class is exposed as “custom-recipient” object class through LDAP. This object class contains all the attributes of the organizationalPerson object class noted above with the exception of mailPreferenceOption. The Custom-Recipient object class does contain an additional mandatory attribute with the following properties
LDAP Name | Exchange Name | Mandatory | Heuristic | ACL | Syntax | Comment | |
Target Address | E-mail Address | Y | 18 | 1 | String(Unicode) | Actual address of the recipient (this address is in the format <address Type>:<value> e.g. SMTP:jsmith@org.com |
The Distribution-List object class is exposed as the groupOfNames object class through LDAP. Its attributes are:
LDAP Name | Exchange Name | Mandatory | Heuristic | ACL | Syntax | COMMENT |
Company | Company | FALSE | 18 | 1 | String(Unicode) | Mainly for AB View grouping |
department | Department | FALSE | 18 | 1 | String(Unicode) | Mainly for AB View grouping |
physicalDeliveryOfficeName | office | FALSE | 18 | 1 | String(Unicode) | Mainly for AB View grouping |
st | State-Or-Province-Name | FALSE | 18 | 1 | String(Unicode) | Mainly for AB View grouping |
title | Title | FALSE | 18 | 1 | String(Unicode) | Mainly for AB View grouping |
co | Text-Country | FALSE | 18 | 2 | String(Unicode) | Mainly for AB View grouping |
l | City | FALSE | 18 | 2 | String(Unicode) | Mainly for AB View grouping |
Hide-DL-Membership | Hide-DL-Membership | FALSE | 20 | 1 | Boolean | Indicates if he Membership should be hidden from the client (default is FALSE). |
owner | Owner | FALSE | 20 | 1 | Object(DS-DN) | The DN of the Mailbox that "owns" this Distribution List. |
member | Members | FALSE | 20 | 2 | Object(OR-Name) | The list of DNs that are members of the Distribution List |
In certain applications, such as a directory synchronization service, it is important to get incremental changes out of the Exchange directory. This can be achieved by performing searches on the following operational attributes, which exist on every object in the Exchange directory:
USN-Changed: | This is an integer that is incremented by the Exchange directory every time a modification is made to an object (deletions are treated as any other modification to the object). |
USN-Created: | This is an integer that represents when an object was created in the Exchange directory. |
When-Changed: | This is the UTC time when the object was changed. |
When-Created: | This is the UTC time when the object was created. |
By keeping track of USN-Changed/Created or When-Changed/Created, an application can get at changes in the Exchange directory since the last time it polled for changes.
These attributes are available to any authenticated user.
Just as important as retrieving incremental changes from the Exchange Directory is the capability of retrieving deleted objects. This can be done by binding using clear text authentication with “,cn=admin” appended to the user’s DN (e.g. dc=domain,cn=jsmith,cn=admin).
When a client is authenticated with the Exchange Directory with “,cn=admin” in the user’s DN, it will be able to query for an operational attribute called “is-deleted”. This attribute is a Boolean attribute that indicates whether the object has been deleted or not. A deleted object is referred to as a tombstone. Tombstones exist for a period of time indicated by the “Tombstone lifetime” parameter on the DS Site Configuration property page in the Microsoft Exchange Admin program. By default, the “Tombstone lifetime” is set to 30 days. If your application depends on getting deletions out of the Exchange Directory you should make sure that it runs within the “Tombstone lifetime” period.
This section contains a couple of ADSI samples that demonstrate authentication against the Exchange directory, searches for objects using ADO, and manipulation of objects using ADSI.
The code below will create a distribution list and populate it with the users found via an ADO query:
Option Explicit
Dim strDisplayName ' DL's Display name
Dim strAliasName ' DL's Alias name
Dim strDirectoryName ' DL's Directory name
Dim strUserName ' User's logon name and domain
Dim strPassword ' User's domain password
Dim strServer ' Exchange server name
Dim strOrganization ' Exchange Organization
Dim strSite ' Exchange Site
Dim strRecipientsPath ' ADsPath to the Recipients Container
Dim strMSPrivMDBPath ' ADsPath to the MS Private MDB
Dim objRecipients ' Recipients Container object
Dim objMSPrivMDB ' MS Private MDB object
Dim objNewDL ' new distribution list object
Dim strMail ' mail address of the MS Private MDB object
Dim intPos ' numeric position of the '@' in an SMTP address
Dim strSMTPExt ' SMTP domain type (ie. com, org, etc...)
Dim strSMTPAddr ' new DL's SMTP address
Dim aOtherMailbox(1) ' other addresses created (ie. MSMail, CCMail)
Dim strx400Addr ' new DL's X400 address
Dim objMyIADs ' ADSI object
' used by the PutEx method to set a muti-valued property
Const ADS_PROPERTY_UPDATE = 2
strDisplayName = "BellevueDL"
strAliasName = "BellevueDL"
strDirectoryName = "BellevueDL"
strUserName = "dc=redmond, cn=v-sparke"
strPassword = "password"
strServer = "sparker1"
strOrganization = "16"
strSite = "3081"
Set objMyIADs = GetObject("LDAP:")
The following code determines the domain address extension by looking at the ‘'mail' property of the well-known “Microsoft Private MDB” object:
strMSPrivMDBPath = "LDAP://" + strServer + "/cn=Microsoft Private MDB,cn=" + strServer + ",cn=Servers ,cn=Configuration,ou=" + strSite + ",o=" + strOrganization
This application uses the OpenDSObject method to access directory objects. The user's logon domain, name and password are passed as parameters. The value of 0 means that the ADSI LDAP provider will do a simple bind:
Set objMSPrivMDB = objMyIADs.OpenDSObject(strMSPrivMDBPath, strUserName, strPassword, 0)
objMSPrivMDB.GetInfo
strMail = objMSPrivMDB.Get("mail")
intPos = InStr(strMail, "@")
strSMTPExt = Mid(strMail, intPos, Len(strMail))
The code below builds SMTP, MSMAIL, CCMAIL, and X400 addresses. "US" is hardcoded into the X400 address. The textEncodedORaddress property of the MS Private MDB object may be parsed to determine the correct X400 addressing scheme:
strSMTPAddr = replace(strAliasName, " ", "") + strSMTPExt
aOtherMailbox(0) = CStr("MS$" + strOrganization + "/" + strSite + "/" + strAliasName)
aOtherMailbox(1) = CStr("CCMAIL$" + strAliasName + " at " + strSite)
strx400Addr = "c=US;a= ;p=" + strOrganization + ";o=" + strSite + ";s=" + strAliasName + ";"
strRecipientsPath = "LDAP://" + strServer + "/cn=Recipients,ou=" + strSite + ",o=" + strOrganization
Set objRecipients = objMyIADs.OpenDSObject(strRecipientsPath, strUserName, strPassword, 0)
This code creates the distribution list:
Set objNewDL = objRecipients.Create("groupOfNames", "cn=" + strDirectoryName)
Note that in VBScript, it is necessary to CStr() string values to properly format the data for ADSI:
objNewDL.Put "cn", CStr(strDisplayName)
objNewDL.Put "uid", CStr(strAliasName)
objNewDL.Put "distinguishedName", CStr("cn=" + strAliasName + ",cn=Recipients,ou=" + strSite + ",o=" + strOrganization)
objNewDL.Put "mail", CStr(strSMTPAddr)
This code creates a multivalued property. In VBScript you have to de-reference the array by using parentheses:
objNewDL.PutEx ADS_PROPERTY_UPDATE, "otherMailbox", (aOtherMailbox)
objNewDL.Put "Report-To-Originator", True
objNewDL.Put "Report-to-Owner", False
objNewDL.Put "Replication-Sensitivity", CInt(20)
objNewDL.Put "rfc822Mailbox", CStr(strSMTPAddr)
objNewDL.Put "textEncodedORaddress", CStr(strx400Addr)
objNewDL.SetInfo
Response.Write "DL Created Successfully!<BR><BR>"
The code below will find mailboxes in the Exchange directory services whose "City" property matches the search criteria. The ADSI LDAP name for "City" property is "l."
Dim objADOconn ' ADO connection object
Dim strADOQueryString ' ADO query string
Dim objRS ' recordset object
Dim strCriteria ' value used to search the directory tree
strCriteria = "Bellevue"
Set objADOconn = CreateObject("ADODB.Connection")
objADOconn.Provider = "ADSDSOObject"
objADOconn.Open "ADs Provider"
strADOQueryString = "<LDAP://" + strServer + ">;(&(objectClass=organizationalPerson)(l=" + strCriteria + "));cn,adspath;subtree"
Set objRS = objADOconn.Execute(strADOQueryString)
If Not objRS.EOF Then
While Not objRS.EOF
objNewDL.Add objRS.Fields(1).Value
Response.Write objRS.Fields(0) + " added :)<BR>"
objRS.MoveNext
Wend
Else
Response.Write "No mailboxes were added to the DL :(<BR>"
End If
objRS.Close
This code will modify the Phone number property of a mailbox. All users have access to modify this property on their mailbox by default.
This following code will cause the browser to pop up a user-identification dialog box. The IIS server's password authentication must be set to "Allow Anonymous" and "Basic (Clear Text)" only. This way, the browser will be able to use the correct security context when using the GetObject method.
Dim strAT ' Authorization Type information
strAT = Request.ServerVariables("AUTH_TYPE")
If InStr(1, "_BasicNTLM", strAT, 1) < 2 Then
Response.Buffer = True
Response.Status = ("401 Unauthorized")
Response.End
End If
Dim strMailboxPath ' ADsPath to the user's mailbox
Dim strServer ' name of the Exchange 5.5 server
Dim intPosPrefix ' numeric index used used to build ADsPath to schema object
Dim intPosSuffix ' numeric index used used to build ADsPath to schema object
Dim strPrefix ' prefix string used to build ADsPath to schema object
Dim strSuffix ' suffix string used to build ADsPath to schema object
Dim strPathToSchemaObject ' ADsPath to the schema object
Dim objMailbox ' mailbox object
Dim strNewPoneNumber ' value of the new phone number
Function isUserEditable(strSchemaObjectPath)
Dim objSchemaObject ' schema object
Dim intValue ' value of the Access-Category property
Set objSchemaObject = GetObject(strSchemaObjectPath)
intValue = objSchemaObject.Get("Access-Category")
If intValue = 2 Then ' user may modify the mailbox property
isUserEditable = True
Else ' the value was 0, 1, or 3
isUserEditable = False
End If
End Function
This procedure will modify the property of an object that contains a string value. To set a property to the empty string, you must remove it from the object:
Sub ModifyProperty(strNewValue, strADsProperty)
On Error Resume Next
If Len(strNewValue) <> 0 Then
objMailbox.Put strADsProperty, CStr(strNewValue)
Else ' The new value is empty
objIADs.Get (strADsProperty)
If the property doesn't exist on the object, an error will be generated using the Get method:
If Err.Number = 0 Then ' the property exists on the object and must be removed
objMailbox.PutEx ADS_PROPERTY_CLEAR, strADsProperty, CStr(" ")
End If
Err.Clear
End If
End Sub
Const ADS_PROPERTY_CLEAR = 1 ' used by the PutEx method to clear a property from an object
strMailboxPath = "LDAP://SPARKER1/cn=SParker,cn=Recipients,ou=3081,o=16"
strServer = "sparker1"
strNewPoneNumber = "(425) 882-8080 x 13882"
intPosPrefix = InStr(strMailboxPath, "/cn")
intPosSuffix = InStr(strMailboxPath, "ou")
strPrefix = Mid(strMailboxPath, 1, intPosPrefix - 1) + "/cn="
strSuffix = ",cn=Microsoft DMD," + Mid(strMailboxPath, intPosSuffix, Len(strMailboxPath))
strPathToSchemaObject = strPrefix + "Telephone-Office1" + strSuffix
If isUserEditable(strPathToSchemaObject) Then
Set objMailbox = GetObject(strMailboxPath)
ModifyProperty strNewPoneNumber, "telephoneNumber"
objMailbox.SetInfo ' save the object information
Response.Write "Phone number modified successfully :)<BR>"
Else
Response.Write "You don't have permissions to modify your phone number :(<BR>"
End If
%>
ADSI cannot yet manipulate Access Control Lists (ACLs), which contain security information about which user has rights on a certain object. It cannot get the Windows NT Security Identifier (SID), the binary representation of a user’s account name, and thus cannot set the bits necessary to create the user’s rights. Thus developers cannot create a functional Mailbox object completely with ADSI, since a mailbox object requires the NT account SID in the Assoc-NT-Account attribute as well as the correct security rights on the mailbox object in the NT-Security-Descriptor attribute. The capability to manipulate ACLs is expected in a future release.
Because ADSI frees developers from involvement in directory-specific APIs, it makes administrative functions more flexible. For example, a directory-specific API might require an administrator to key in a security password and domain on an Active Server Page, exposing it to risk. By contrast, ADSI objects force the Web browser to prompt the administrator.
Once a developer learns the ADSI convention, it is easy to write an LDAP path name and specify the class and property of an object. Exchange 5.5 will bring up an ADSI page that allows developers to type in the appropriate Exchange Server, pull it from the registry and populate the server field. By using ADSI objects, they can develop a variety of easy-to-use applications. For example, developers can write a Web-server script that allows a browser to look up details of users represented in different directories. Or, they can create a distribution list manager that creates distribution lists from users in different directories. Or, they can specify access privileges for printer queues. With the flexibility of ADSI, the possibilities are manifold.
Designed to provide a single, consistent open set of interfaces for heterogeneous directory services, ADSI provides an important common ground in today’s far-flung enterprise networks and intranets. Furthermore, it enables Exchange administrators and developers to write applications and to port Exchange Directory Access Programming Interface (DAPI)-based applications to ADSI. These applications will run in Exchange 5.5 environments and with minimal or no changes can run on top of the Windows NT 5 Active Directory. Exchange developers and administrators can thus more easily keep pace with changes while developing directory-enabled applications more efficiently.
Visit the following Web sites for more information: