Exchange Server
ADSI together with the LDAP provider can be used to perform operations against Exchange server 5.5 and 2000. Using this interface, most administrative tasks can be performed, such as mailbox, custom mailbox, and distribution list manipulation.
Administrative tasks are performed differently in Exchange 2000 and Exchange 5.5. Code written for Exchange 5.5 will not work under Exchange 2000 and vice versa. This chapter provides solution code and discussions for each platform.
Creating a Mailbox
Problem
You want to create a new Exchange mailbox.
Solution
To create a mailbox for Exchange 5.5, get a reference to the container you want to create the mailbox in and create an instance of an organizationalPerson object:
'createmailbox.vbs Const ADS_RIGHT_EXCH_MODIFY_USER_ATT = 2 Const ADS_RIGHT_EXCH_MAIL_SEND_AS = 8 Const ADS_RIGHT_EXCH_MAIL_RECEIVE_AS = 16 Const ADS_SID_WINNT_PATH = 5 Const ADS_SID_HEXSTRING = 1 Dim objMailbox, objContainer, strServer Dim strAlias, strMTA, strMDB, strSMTPAddr, strDisplayName Dim objSid, strSidHex, strComputer, strSite, strOrg Dim objComputer, strUserID, strDomain Dim objSec, objSD, objDACL, objAce strServer = "Odin" strSite = "Office" strDomain = "Acme" strDisplayName = "Fred Smith" strSMTPAddr = "FredSmith@acme.com" strAlias = "Freds" strUserID = "Freds" Set objComputer = GetObject("LDAP://" & strServer) 'get the organization strOrg = objComputer.o 'get the recipients container for the site Set objContainer = _ GetObject("LDAP://" & strServer & "/CN=Recipients,OU=" _ & strSite & ",o=" & strOrg) 'get the SID for the account to be associated with the new mailbox Set objSid = CreateObject("ADsSID") objSid.SetAs ADS_SID_WINNT_PATH, "WinNT://" & strDomain & "/" & strUserID strSidHex = objSid.GetAs(ADS_SID_HEXSTRING) 'create a new MailBox Set objMailbox = objContainer.create("organizationalPerson", "cn=" & strAlias) 'set display name and alias objMailbox.Put "mailPreferenceOption", 0 objMailbox.Put "cn", strDisplayName objMailbox.Put "uid", strAlias objMailbox.Put "Home-MTA", _ "cn=Microsoft MTA,cn=" & strServer & ",cn=Servers,cn=Configuration,ou=" _ & strSite & ",o=" & strOrg objMailbox.Put "Home-MDB", _ "cn=Microsoft Private MDB,cn=" & strServer & _ ",cn=Servers,cn=Configuration,ou=" _ & strSite & ",o=" & strOrg objMailbox.Put "MAPI-Recipient", True 'objMailbox.Put "rfc822Mailbox", strSMTPAddr objMailbox.rfc822Mailbox = strSMTPAddr objMailbox.Put "textEncodedORaddress", _ "c=US;a= ;p=" & strSite & ";o=" & strOrg & ";s=" & strAlias objMailbox.textEncodedORaddress = _ "c=US;a= ;p=" & strSite & ";o=" & strOrg & ";s=" & strAlias objMailbox.Put "Assoc-NT-Account", strSidHex objMailbox.SetInfo 'create security objects Set objSec = CreateObject("ADsSecurity") Set objAce = CreateObject("AccessControlEntry") Set objSD = objSec.GetSecurityDescriptor("LDAP://" & strServer & _ "/CN=Recipients,OU=" & strSite & ",o=" & strOrg) Set objDACL = objSD.DiscretionaryAcl objAce.Trustee = strDomain & "" & strUserID objAce.AccessMask = ADS_RIGHT_EXCH_MODIFY_USER_ATT Or _ ADS_RIGHT_EXCH_MAIL_SEND_AS Or _ ADS_RIGHT_EXCH_MAIL_RECEIVE_AS objAce.AceType = ADS_ACETYPE_ACCESS_ALLOWED objDACL.AddAce objAce objSD.DiscretionaryAcl = objDACL objSec.SetSecurityDescriptor objSD
To create an Exchange 2000 mailbox, reference the user from the Windows 2000 Active Directory and invoke the CreateMailbox method:
'create a Exchange 2000 mailbox Dim strServer, strDomain, strOrganization, strAdminGroup Dim strStorageGroup, strStoreName Dim objPerson, objMailbox strServer = "Odin " strDomain = "acme.com" strOrganization = "acme" strAdminGroup = "First Administrative Group" strStorageGroup = "First Storage Group" strStoreName = "Mailbox Store (Odin)" 'get a user object from Active Directory to create mailbox for Set objMailbox = GetObject("LDAP://cn=Fred Smith,cn=Users,dc=acme,dc=com") ' create mailbox for specified server objMailbox.CreateMailbox "LDAP://" & _ strServer & _ "/CN=" & _ strStoreName & _ ",CN=" & _ strStorageGroup & ",CN=InformationStore,CN=" & _ strServer & _ ",CN=Servers,CN=" & _ strAdminGroup & "," & _ "CN=Administrative Groups,CN=" & _ strOrganization & "," & _ "CN=Microsoft Exchange,CN=Services," & _ "CN=Configuration,dc=acme,dc=com" objMailbox.SetInfo
Discussion
To create a new Exchange 5.5 object, you must first obtain a reference to a container:
Set objContainer = GetObject("LDAP://server/CN=container,OU=site,o=organization")
where the server is the name of the Exchange server and the container is the mailbox container. Exchange server creates a Recipients container by default. Site is the Exchange site name and organization is the Exchange organization.
To get a reference to the Recipients container for the office site in the Acme organization, use the following:
Set objContainer = _ GetObject("LDAP://odin/CN=Recipients,OU=office,o=acme")
The Exchange directory structure is hierarchical, so containers can be nested within containers, allowing groups of objects to be broken down and organized in a logical fashion. To reference a container in a hierarchy, prefix the LDAP path with the container names separated by commas. In the following example, a reference is made to the Accounting container, which has been created below the Recipients container:
Set objContainer = _ GetObject("LDAP://odin/CN=Accounting,CN=Recipients,OU=office,o=acme")
Exchange mailboxes are created in mailbox containers. A mailbox is an organizationalPerson object class. To create a new mailbox, invoke the Create method on the container where the mailbox will reside. The mailbox is identified using a relative distinguished name (RDN), which in the case of a mailbox is cn= followed by the alias for the mailbox. The mailbox alias can be up to 64 characters and include spaces, but you should follow naming conventions used when creating accounts in the Exchange 5.5 Administrator program:
'Create a new MailBox for Fred smith using the alias Freds Set objMailbox = objContainer.create("organizationalPerson", "cn=FredS")
A new object of type organizationalPerson is created in the container specified by the objContainer object and is assigned a container name (cn) of FredS. The cn property maps to the alias under the Exchange 5.5 administration piece.
Before a mailbox can become functional, the properties in Table 16-1 must be set.
PROPERTY |
DESCRIPTION |
---|---|
cn |
Descriptive mailbox display name (e.g., Accountant Fred Smith). |
Uid |
Unique mailbox alias, usually a combination of the first and last name of a user (e.g., Freds). |
Home-MTA |
Home-MTA is the default message transfer agent for the mailbox, which is the server the mailbox resides on. It has the following format: Home-MTA, cn=Microsoft MTA,cn=Server, cn=Servers,cn=Configuration,ou=Site,o=Organization |
Server |
Server name. |
Organization |
Exchange organization. |
Site |
Exchange site. For example: Home-MTA, cn=Microsoft MTA,cn=Odin, cn=Servers,cn=Configuration,ou=HeadOffice,o=Acme |
Home-MDB |
Home-MDB is the home server for the mailbox. It has the following format: cn=Microsoft Private MDB,cn=Server,cn=Servers, cn=Configuration,ou=Site,o=Org |
Server |
Server name. |
Organization |
Exchange organization. |
Site |
Exchange site. |
MAPI-Recipient |
Boolean value. Set to True if the mailbox is to be accessible by MAPI clients. |
rfc822Mailbox |
Default Internet address (e.g., freds@acme.com). |
TextEncodedORaddress |
X.400 address. This address is required for Exchange to perform global routing of messages. It has the following format: c=CountryCode;a= ;p=Org;o=Site;s=Alias |
CountryCode |
Country code (e.g., US). |
Server |
Server name. |
Organization |
Exchange organization. |
Site |
Exchange site. To determine how X.400 addresses are generated for your site, check the Site Addressing option under the Configuration container in the Exchange administration piece. Note that there must be an entry or a blank space for the a= component of an X.400 address (known as the administrative management domain name). |
An NT user or group account must be associated with the mailbox to make it functional. The NT account's security identifier (SID) is used to identify what NT account is associated with the Exchange mailbox. The SID uniquely identifies the NT account and is represented as a string of hexadecimal values.
The SID can be retrieved from an ADSI Windows NT User object's objectSid property, which is a multivalued property that contains byte values representing the SID. The current version of VBScript cannot convert this data type.
Instead you will use an ADSI 2.5 SDK DLL to get the SID. This is a COM component called ADsSID that is part of the ADsSecurity DLL from the ADSI SDK. To use the DLL, register the ADsSecurity.dll using regsvr32.exe.
The ADsSecurity.dll doesn't depend upon the SDK for support libraries, so it can be copied from a machine that has the SDK installed to the required machine. It does require ADSI 2.5, which is installed by default on Windows 2000 and XP. ADSI is available as a separate installation on Windows NT 4.0.
An SID can be retrieved from a Windows NT user account using the ADsSID component. Create an instance of the component using the ProgID ADsSID and invoke the SetAs method:
objSid.SetAs nPath,strPath
The nPath parameter determines the path type for the object you are trying to get the SID from. ADS_SID_WINNT_PATH has the value 5 and indicates a Windows NT path, while ADS_SID_ACTIVE_DIRECTORY_PATH has the value 6 and indicates an LDAP Active Directory path.
The strPath parameter is the ADSI path to the object. For Windows NT user accounts, specify the path to the account using the ADSI WinNT provider path format, WinNT//domain/account. For the NT account Freds for the domain Acme, the path would be WinNT://acme/freds. See Chapter 14 for more information on the WinNT ADSI provider.
To return the SID in the appropriate format, use the GetAs method:
SID = objSid.GetAs (nType)
The nType parameter determines the format the SID is to be returned in. The Exchange server account requires it in a hexadecimal string format, which can be specified using the constant ADS_SID_HEXSTRING, which has the value 1.
The following code snippet returns the SID for account Freds from the Acme domain in a string format:
Const ADS_SID_HEXSTRING = 1 Const ADS_SID_WINNT_PATH = 5 Set objSid = CreateObject("ADsSID") objSid.SetAs ADS_SID_WINNT_PATH, "WinNT://acme/freds" strSidHex = objSid.GetAs(ADS_SID_HEXSTRING)
Once you have a user's SID string, assign it to the mailbox's Assoc-NT-Account property:
objMailbox.Put "Assoc-NT-Account", strSidHex 'set associated NT user
The final step in making the mailbox active is setting the mailbox security.
The user associated with the mailbox needs appropriate security access to the mailbox in order to use it. A standard Exchange mailbox allows a user to maintain his or her mailbox configuration, and send and receive messages. This security setting is automatically assigned to a mailbox created using the Exchange Server 5.5 Administrator. The option to view security details is not displayed in the Exchange Administrator by default, but it can be listed by changing the setting under the Options menu.
This security access is not directly accessible through ADSI. The security can be set using the AdsSecurity DLL provided by the ADSI 2.5 SDK. Like the ADsSID component, which also comes from the SDK, the SDK does not need to be installed on every computer using it, and the DLL can be copied and registered on any computer that requires it. The computer does require ADSI 2.5 or later to be installed.
The ProgID for the component is AdsSecurity. Get the security descriptor for the mailbox object you want to add the security to by invoking the security object's GetSecurityDescriptor method, specifying the path to the ADSI you want to retrieve the security details for.
The following code sample gets the security descriptor for the mailbox Freds:
'create an instance of the ADsSecurity object Set objSecurity = CreateObject("ADsSecurity") 'get the security descriptor for a object strMailbox = "LDAP://odin/cn=Freds,cn=Recipients,ou=office,o=acme" Set objSD = objSecurity.GetSecurityDescriptor(strMailBox)
The object's security descriptor contains all security information related to the object, such as owner, access, and security auditing. The security access is stored in the Discretionary Access Control List (DACL). The DACL contains a list of Access Control Entries (ACEs). Each ACE either allows or denies access to a particular operation.
A general Exchange mailbox allows a user to send mail, receive mail, and modify mailbox settings. To achieve this, you must add a new ACE to the DACL that assigns the appropriate access to the mailbox.
First you get the DACL and create a new ACE, which you do by referencing the security descriptor object's DiscretionaryACL property:
'get discretionary ACL for the object Set objDACL = objSD.DiscretionaryAcl Set objAce = CreateObject("AccessControlEntry")
Set the ACE object's Trustee property to the account you want to assign to the mailbox. The trustee represents a NT user account in the format domainaccountname:
'set the user id to add security for objAce.Trustee = "AcmeFreds"
The ACE object exposes an AccessMask property that determines what operations a particular user can perform against the mailbox. The AccessMask property is a numeric value, which consists of one or more values that identify what operations a user can perform.
A user by default has the ability to send and receive mail and modify his or her account. The values for these operations are 2, 8, and 16 for modify, send, and receive, respectively.
The AceType property determines if the user is granted or denied access to the operations specified by the AccessMask property. To grant access, set AceType to 0, and to deny access, set it to 1.
The following snippet demonstrates how to assign the rights to the AccessMask property:
Const ADS_RIGHT_EXCH_MODIFY_USER_ATT = &H2 Const ADS_RIGHT_EXCH_MAIL_SEND_AS = &H8 Const ADS_RIGHT_EXCH_MAIL_RECEIVE_AS = &H10 Const ADS_ACETYPE_ACCESS_ALLOWED = 0 'allow trustee to modify user attributes, send and receive mail objAce.AccessMask = ADS_RIGHT_EXCH_MODIFY_USER_ATT Or _ ADS_RIGHT_EXCH_MAIL_SEND_AS Or ADS_RIGHT_EXCH_MAIL_RECEIVE_AS objAce.AceType = ADS_ACETYPE_ACCESS_ALLOWED 'set access
Once the operations are complete, add the ACE to the DACL using the AddAce method. Update the security descriptor on the mailbox with the new settings by invoking the SetSecurityDescriptor method, specifying the updated security descriptor object:
objDACL.AddAce objAce 'add the ACE to DACL objSD.DiscretionaryAcl = objDACL objSecurity.SetSecurityDescriptor objSD
You can find more information on security operations in Chapter 17.
The following script, createxusr.wsf, allows for the creation of Exchange 5.5 mailboxes from the command line:
The script creates a new Exchange mailbox and associates it with a specified NT user account. The command-line syntax is as follows:
createxuser server site alias displayname SMTPAddress domain accountName
Server is the name of the Exchange server, site is Exchange server site, alias is the Exchange mailbox alias, displayname is the Exchange mailbox display name, SMTPAddress is the Internet mail address, domain is the name of the NT domain to find associated user account, and accountname is the NT user account.
The following command line creates the Exchange mailbox for the user Fred Smith with an alias freds and the Internet address freds@acme.com, and associates the mailbox with the NT account freds on the Acme domain:
createxuser.wsf Odin Acme Freds "Fred Smith" freds@acme.com Acme freds
The script requires that ADSI version 2.5 or later is installed and also requires that the AdsSecurity DLL from the ADSI 2.5 SDK is installed and registered on the computer the script is run from. The script does not have to run on a computer where Exchange server is installed.
Creating a user for Exchange 2000 is easier than in Exchange 5.5 because the mailbox is associated with an Active Directory user. Because Active Directory performs the directory operations implemented separately in Exchange 5.5, fewer steps are required than in Exchange 5.5, especially the tedious step of assigning a Windows NT account to the new mailbox.
Exchange 2000 mailbox maintenance is made even easier by the introduction of Collaborative Data Objects for Exchange Management library (CDOEXM). CDOEXM provides a number of methods that help simplify Exchange 2000 maintenance operations, such as the creation and deletion of mailboxes.
CDOEXM extends Active Directory, providing transparent functionality to Active Directory objects. You can use your existing knowledge of Active Directory objects and functionality while implementing new Exchange administrative functionality by calling methods and setting properties exposed by CDOEXM.
Note |
If you are running code that uses the CDOEXM library on a machine other than the Exchange 2000 server, you must install the Exchange Management Components from the Exchange 2000 installation package. |
To create a new mailbox, reference the Active Directory user object you want to create a mailbox for and invoke the CreateMailbox method. CreateMailbox requires a single parameter: the path to Exchange 2000 mailbox store where you want to create the mailbox. This consists of the Exchange server, directory, and mail store where you want the mailbox to reside.
This path is not very intuitive or easy to build and requires decent knowledge of your Exchange server installation. One way of assisting in building the path is to do a test user creation using the Microsoft Active Directory Users and Computer administration piece.
Right-click a user that has no mailbox enabled and select the Exchange Tasks option. From the Tasks dialog box, select the Create Mailbox option. A dialog box similar to the one in Figure 16-1 appears.
Figure 16-1: Create Mailbox dialog box
Select the server and mailbox store you want to create the mailbox in. The Server field consists of the organization, administration group, and server separated by forward slashes (/).
The Mailbox Store field contains the storage group and mailbox store separated by forward slashes. The following code builds the path to the mailbox store, as shown in Figure 16-1:
'these strings are built from the Server field strOrganization = "acme" strAdminGroup = "First Administrative Group" strServer = "Odin " ' Exchange server name 'these strings are built from the Mailbox Store field strStorageGroup = "First Storage Group" ' storage group strStoreName = "Mailbox Store (Odin)" 'mail store name strDomain = "acme.com" 'strPath = "LDAP://" & _ strServer & _ "/CN=" & _ strStoreName & _ ",CN=" & _ strStorageGroup & ",CN=InformationStore,CN=" & _ strServer & _ ",CN=Servers,CN=" & _ strAdminGroup & "," & _ "CN=Administrative Groups,CN=" & _ strOrganization & "," & _ "CN=Microsoft Exchange,CN=Services," & _ "CN=Configuration,dc=acme,dc=com"
Another way of determining the mailbox store path is to use the Active Directory browser ADSI Edit to navigate the path. ASDI Edit is included under the SUPPORTTOOLS directory on the Windows 2000 CD. Figure 16-2 shows the path to a mailbox store.
Figure 16-2: Path to the mailbox store in ASDI Edit
Once you find the mailbox store, double-click it and copy the path to the CreateMailbox method.
See Also
For more information, read the MSDN Library article "CreateMailBox Method" (http://msdn.microsoft.com/library/en-us/wss/_cdo_imailboxstore_createmailbox.asp).
Setting Mailbox Properties
Problem
You want to set mailbox properties.
Solution
For Exchange 5.5, get a reference to the mailbox you want to set the property for, set the properties you want to change, and invoke the SetInfo method to write the changes back to the Exchange 5.5 directory:
'get a reference to the Freds mailbox Set objMailbox = _ GetObject("LDAP://odin/cn=Freds,cn=Recipients,ou=office,o=Acme") 'set the container name to Fred Smith objMailBox.cn = "Fred Smith" objMailBox.SetInfo
For Exchange 2000 mailboxes, reference the Active Directory user object and set the required properties:
'get a reference to the Fred Smith Active Directory user object Set objUser = _ GetObject("LDAP://cn= Fred Smith,cn=Users,dc=acme,dc=com") 'set the container name to Fred Smith objUser.cn = "Fred Smith" objUser.SetInfo
Discussion
To set properties for an Exchange 5.5 object, get a reference to the Exchange 5.5 directory object you want to set properties for using the LDAP provider:
Set objMailbox = _ GetObject("LDAP://server/cn=alias,cn=container,ou=site,o=organization")
You can set properties using the Put method or the dot method:
'the following statements perform the same operation objMailBox.cn = "Fred Smith" objMailBox.Put "cn", "Fred Smith" objMailBox.SetInfo
Once you have set the properties, invoke the SetInfo method to set update the properties in the Exchange directory.
Exchange exposes many properties that contain hyphens (-). They require that the Get/Put method is used when referencing/setting values:
Wscript.Echo objMailBox.Get ("Submission-Cont-Length")
There are many properties that do not get loaded into the ADSI cache automatically. Referencing these properties using the dot or Get method generates a runtime error, even if the property is valid. To get a reference to these properties, you must use the GetInfoEx method to "force" them to be loaded:
objMailbox.GetInfoEx aProperties, nValue
The aProperties parameter is an array of property names you want to load. The nValue parameter is currently not used and must be set to 0:
objMailbox.GetInfoEx Array("Deliv-Cont-Length"), 0 Wscript.Echo objMailBox.Get ("Deliv-Cont-Length")
These properties can be set using the normal Put or dot methods. There are no specific rules as to which properties require GetInfoEx to read their value.
Objects stored in the Exchange directory, such as mailboxes and distribution lists, contain a large number of properties that can be manipulated.
The Microsoft Exchange Administrator application allows for the viewing and manipulation of these Exchange objects. It can be started in "raw" mode, which provides the ability to view Exchange object internal property names. This can be useful in determining the name of a property to modify using WSH and ADSI.
To start the Exchange administrator in raw mode, follow these steps:
- Create a command prompt.
- Find the location of the Exchange Administrator application. By default it is installed in the c:exchsrvrin directory.
- Enter the command admin /r. This starts the Exchange Administrator program in raw mode.
Select the object you want to view and select File > Raw Properties.
The attributes displayed in the dialog box are how the Exchange directory references the information. They do not all correspond to Active Directory/LDAP object properties.
To map the Exchange attribute name to its LDAP counterpart, note the attribute name and turn on raw directory mode by selecting View > Raw Directory.
You will notice that a Schema icon entry appears in the list of server containers. Selecting this icon will list Exchange directory attributes in the right-hand window pane.
Select the attribute name you want to reference through LDAP and view its property. View the Description of the attribute to get the LDAP name.
The result is the Exchange directory City attribute maps to the L property under LDAP, as shown in Figure 16-3.
Figure 16-3: Exchange Administrator raw mode
Table 16-2 lists a number of commonly used Exchange mailbox properties and what field they map to in the Exchange Administrator program.
PROPERTY |
DESCRIPTION |
---|---|
cn |
Display name |
co |
Country code |
Company |
Company name |
Department |
Department name |
FacsimileTelephoneNumber |
Fax number |
HomeFax |
Home fax number |
HomePhone |
Home phone number |
info |
Notes |
Initials |
User initials |
L |
City |
Mobile |
Mobile phone number |
Pager |
Pager number |
PhysicalDeliveryOfficeName |
Office |
PostalAddress |
Address |
PostalCode |
Postal/ZIP code |
Secretary/Telephone-Assistant |
Assistant |
sn |
Last name |
St |
State |
Telephone-Home2 |
Second home phone number |
Telephone-Office2 |
Business phone number |
TelephoneNumber |
Primary phone number |
title |
Business title |
The mailbox object exposes a great deal more properties than listed in the previous table. One way to list other properties and the corresponding entry in the Exchange Administrator is to create a "dummy" user, set properties using the Exchange Administrator, and then enumerate the object properties.
The listprop command-line script from Solution 14.5 requires a valid ADSI object. All properties and any related values are output. The following command line outputs all properties for the mailbox JoeB on the server Odin:
listprop LDAP://odin/cn=Joeb,cn=Recipients,ou=Office,o=Acme
The following script, xchgmaint.wsf, updates Exchange 5.5 mailbox properties from standard input:
The command line syntax is as follows:
xchgmaint.wsf server site [/d:delimiter]
in which server is the name of the Exchange 5.5 server, and site is the Exchange server site.
The standard input format requires input where the first column represents the mailbox alias and any following columns represent properties to be set. The first row must contain the property names. The following listing represents a text file that contains information to update mailboxes with:
alias,telephoneNumber,title, department freds,555-1234,Accounting Manager, Accounting
To update the mailboxes, pipe the output of the file to the xchgmaint.wsf script. The following command-line sample pipes the file mbupdate.txt to the xchgmaint.wsf script for the Exchange site office on server Odin:
type mbupdate.txt | cscript xchgmaint.wsf Odin office
Because Exchange 2000 relies on Active Directory, the bulk of the properties related to the mailbox, such as personal details and phone numbers, are associated with the Active Directory user object. See Chapter 14 for more details on setting these properties.
Any Exchange 2000-specific properties can be listed using an Active Directory object browser or using the listprop method described earlier.
See Also
For more information, read the MSDN Library article "The Microsoft Exchange Directory Schema" (http://msdn.microsoft.com/library/en-us/exchserv/html/directry_5n35.asp).
Setting Mailbox Limits
Problem
You want to set mailbox storage and message limits.
Solution
You can get a reference to the mailbox object for which you want to set limitations and then set the appropriate property:
Set objMailbox = _ GetObject("LDAP://odin/cn=Freds,cn=Accountants,ou=Office,o=Acme") objMailBox.Put "MDB-Use-Defaults", False 'set the mailbox to send warnings at 10 megabytes objMailBox.Put "MDB-Storage-Quota", 10000 objMailBox.SetInfo
Exchange 2000 mailboxes implement similar control over individual mailboxes but they use different property names than Exchange 5.5 mailboxes:
Set objMailbox = GetObject("LDAP://cn=Fred Smith,cn=Users,dc=acme,dc=com") 'set mailbox storage quota to 2 megabytes objMailbox.StoreQuota = 2000 objMailbox.SetInfo
Discussion
Table 16-3 lists properties for Exchange 5.5 and 2000 that determine mailbox limits.
EXCHANGE 5.5 |
EXCHANGE 2000 |
DESCRIPTION |
---|---|---|
MDB-Over-Quota-Limit |
OverQuotaLimit |
Maximum size of mailbox in kilobytes before sending of messages is prohibited. |
MDB-Storage-Quota |
StoreQuota |
Maximum size of mailbox in kilobytes before warning messages are sent to mailbox. |
DXA-Task |
HardLimit |
Maximum size of mailbox in kilobytes before sending and receiving of messages is prohibited. |
MDB-Use-Defaults |
EnableStoreDefaults |
Boolean. If set to True, default storage limits set under Private Information store configuration are used and the MDB-Over-Quota-Limit, MDB-Storage-Quota, and DXA-Task properties are ignored. |
Garbage-Coll-Period |
DaysBeforeGarbageCollection |
The maximum amount of time deleted messages are stored. For Exchange 5.5 this is stored in minutes, Exchange 2000 the value represents days. |
Because CDOEXM extends the Active Directory, it's transparent to you when you are using the CDOEXM or native Active Directory properties. The advantage of using Active Directory properties over the corresponding CDOEXM versions is that CDOEXM does not have to be on the computer where the code is executed.
See Also
For more information, read the MSDN Library article "Setting Mailbox Storage Limits (2000)" (http://msdn.microsoft.com/library/en-us/wss/wss/_cdo_setting_mailbox_storage_limits.asp).
Creating a Custom Recipient
Problem
You want to create a custom recipient.
Solution
To create a custom Exchange 5.5 recipient, get a reference to the container you want to create the recipient in. Create an object of Remote-Address type and assign a mailbox name, alias, and e-mail address:
Dim objContainer, objMailbox 'get a reference to the Recipients container. This is where the new custom 'recipient will be store Set objContainer = GetObject("LDAP://odin/CN=Recipients,OU=Office,o=Acme") 'create an instance of a Remote-Address object. This is the class custom 'recipients are created Set objMailbox = objContainer.create("Remote-Address", "cn=Fred Smith") objMailbox.Put "cn", "Fred Smith at Hotmail" objMailbox.Put "uid", "FredsHM" objMailbox.Put "Target-Address", "SMTP:freds@hotmail.com" objMailbox.SetInfo
To create an external e-mail address under Exchange 2000, get a reference to either an Active Directory contact or user object and invoke the MailEnable method, specifying the e-mail address you want to associate with the object:
'get user Fred Smith Set objUser = GetObject("LDAP://cn=Fred Smith,cn=Users,dc=acme,dc=com") 'mail enable user with a Internet SMTP address objUser.MailEnable "smtp:freds@hotmail.com" 'update settings objUser.SetInfo
Discussion
Exchange 5.5 and 2000 can contain addresses of external users that do not reside in the organization's Exchange servers. These "custom" recipients are assigned an e-mail address for the specific mail service and appear in the Exchange address list. Examples of this could be external e-mail addresses for customers.
Messages sent to these recipients are not stored on the Exchange server and custom recipients cannot log on to an Exchange server. Custom recipients do not require any associated NT account.
Table 16-4 lists the minimum required properties to make a customer recipient mailbox functional.
PROPERTY |
DESCRIPTION |
---|---|
cn |
Display name that appears in address list and Exchange Administrator. |
Uid |
Unique account alias. |
Target-Address |
Default address associated with account. This is in the format mailtype:address, where mailtype identifies the mail system and address is an address in the format of the specified mail system. Table 16-5 lists built-in address types available to Exchange. Example of Target-Address: SMTP:freds@hotmail.com |
PREFIX |
TYPE |
---|---|
SMTP |
Internet e-mail |
CCMAIL |
CC:Mail |
MS |
Microsoft Mail |
x400 |
X.400 |
Once the properties have been set, invoke the SetInfo method to update the properties in the ADSI cache and Exchange 5.5 server.
Exchange 2000 calls custom recipients mail-enabled contacts. Exchange 2000 introduces another type of custom recipient, a mail-enabled user, which is simply an Active Directory user that appears with an external e-mail address.
Using the CDOEXM library, objects can be mail-enabled objects by calling the MailEnable method. MailEnable requires a forwarding address in the same format as the Exchange 5.5 Target-Address property.
Mail-enabling an Active Directory user object is not the equivalent of an Exchange 5.5 custom recipient. This is accomplished by mail-enabling contact objects.
To create a contact, get a reference to the container that will contain the object and create an object using the contact class:
' get the container where the contact is to be stored Set objContainer = GetObject("LDAP://ou=Contacts,dc=acme,dc=com") 'create the contact Set objContact = objContainer.Create("contact", "CN=Joe SmithCX") 'set a few Active Directory contact object properties objContact.givenName = "Joe" objContact.sn = "Smith" objContact.description = "Joe Smith, Salesperson Company X" objContact.SetInfo objContact.MailEnable "smtp:joes@companyx.com" objContact.SetInfo
In the preceding example, an Active Directory contact is created for Joe Smith in the contacts container. A number of optional properties are set and the contact is mail-enabled using the address joes@companyx.com. The MailEnable method requires the CDOEXM to be installed on the computer where the code is running.
To change the recipient's e-mail address of an existing mail-enabled object, modify the targetAddress property:
'get contact Joe Smith Set objUser = GetObject("LDAP://cn=Joe SmithCX,ou=Contacts,dc=acme,dc=com ") 'change the target address objUser.TargetAddress = "joesmith@hotmail.com" objUser.SetInfo
See Also
For more information, read the MSDN Library articles "Creating a Mail-Enabled Recipient" (http://msdn.microsoft.com/library/en-us/wss/wss/_cdo_creating_a_mail_enabled_recipient.asp) and "Creating a Mail-Enabled Contact" (http://msdn.microsoft.com/library/en-us/wss/wss/_cdo_creating_a_contact.asp).
Maintaining Mailbox E mail Addresses
Problem
You want to add a new e-mail address to a mailbox and delete an existing one.
Solution
For an Exchange 5.5 mailbox, get a reference to the mailbox you want to manipulate e-mail addresses for. Use the PutEx method to add or remove addresses from the mailbox's otherMailbox property:
Const ADS_PROPERTY_APPEND = 3 Const ADS_PROPERTY_DELETE = 4 Dim objMailbox 'get a reference to Freds mailbox Set objMailbox = _ GetObject("LDAP://odin/CN=FredS,CN=Recipients,OU=Office,o=Acme") 'add a new SMTP Internet address to a mailbox objMailbox.PutEx ADS_PROPERTY_APPEND, "otherMailbox", _ Array("smtp$freds@accounting.acme.com") objMailbox.SetInfo 'delete a address from the mailbox objMailbox.PutEx ADS_PROPERTY_DELETE, "otherMailbox", _ Array("smtp$freds@finance.com ") objMailBox.SetInfo
Discussion
An Exchange mailbox can have multiple addresses associated with it. Under Exchange 5.5, mailbox object has the rfc822Mailbox/mail and textEncodedORaddress properties for the default SMTP and X.400 addresses, respectively. But you can have multiple Internet, X.400, MS Mail, and CC:Mail addresses and any other mail service installed on your Exchange server. Different methods are required to perform these operations on Exchange 5.5 and 2000.
For Exchange 5.5 use the otherMailbox property to add custom addresses. The otherMailbox property is multivalued and contains all additional addresses associated with the mailbox. The format of the mail addresses is addresstype$address.
Table 16-5 lists built-in Exchange address types.
The format for a new SMTP e-mail address for <freds@accounting.acme.com> would be <smtp$freds@accounting.acme.com.>
The address type identifies the transport agent that will be used to route and transmit the message.
Because otherMailbox is multivalued, use the PutEx method to update the otherMailbox property. You can add, update, and delete addresses. Call SetInfo each time you add or delete an address.
The following sample demonstrates how to add a new e-mail address for each user in a recipients container:
Dim objContainer, objMailbox 'get a reference to the Recipients container. Set objContainer = GetObject("LDAP://odin/CN=Recipients,OU=Office,o=Acme") 'set a filter on organizationalPerson objects - this will only return 'mailboxes in the conter objContainer.Filter = Array("organizationalPerson") 'loop through each mailbox For Each objMailbox In objContainer 'add a new Internet address to the mailbox, using the mailboxes 'alias as the Internet address name objMailbox.PutEx ADS_PROPERTY_APPEND, "otherMailbox", _ Array("smtp$" & objMailbox.uId & "@acmeus.com") objMailbox.SetInfo Next
Exchange 2000 stores all addresses in a proxyaddresses property. This property is similar to the otherMailbox property in Exchange 5.5 where addresses are stored in an array.
E-mail addresses are manipulated in a similar fashion to Exchange 5.5 using the PutEx method described earlier. The address format is similar to Exchange 5.5, but instead of a dollar sign ($) separating the e-mail type and address, there is a colon (:). The format for a new Exchange 2000 Internet e-mail address for <freds@accounting.acme.com> would be <smtp:freds@accounting.acme.com.>
The case of the e-mail type is important. If the e-mail type is uppercase, it will become the default e-mail address for that e-mail type and will appear as the reply-to address in any mail sent using that mailbox. As a result, the address <SMTP:freds@accounting.acme.com> would show up as the default Internet e-mail address.
Note |
Setting a new primary e-mail address for a mailbox does not reset the preexisting primary address. This must be changed manually. Having multiple primary addresses for the same type in a mailbox may cause the mailbox to function incorrectly. |
In the following example, a new primary address is set for the Fred Smith mailbox and the current primary address is reset to a secondary SMTP address:
Const ADS_PROPERTY_APPEND = 3 Const ADS_PROPERTY_DELETE = 4 'get a reference to Fred's mailbox Set objMailbox = _ GetObject("LDAP://odin/cn=Freds,cn=Accountants,ou=Office,o=Acme") 'add a new SMTP Internet address to a mailbox objMailbox.PutEx ADS_PROPERTY_APPEND, "proxyaddresses", _ Array("SMTP:freds@accounting.acme.com") objMailbox.SetInfo 'delete the current primary SMTP address from the mailbox objMailbox.PutEx ADS_PROPERTY_DELETE, "proxyaddresses", _ Array("SMTP:fred@acme.com") objMailbox.SetInfo 'add the previously delete primary address back, but this time 'as a secondary SMTP address objMailbox.PutEx ADS_PROPERTY_APPEND, "proxyaddresses", _ Array("smtp:fred@acme.com") objMailbox.SetInfo
In the preceding example, the existing primary address, fred@acme.com, is first deleted and then added again with the e-mail type in lowercase.
See Also
Solution 14.7. For more information, read the MSDN Library article "Setting Proxy Addresses" (http://msdn.microsoft.com/library/en-us/wss/wss/_cdo_setting_proxy_addresses.asp).
Creating a Distribution List
Problem
You want to create a distribution list.
Solution
To create a distribution list for Exchange 5.5, get a reference to the parent container where the distribution list will appear and create a groupOfNames object:
Dim objContainer, objDL Dim strDisplayName, strAlias, strSMTPAddr Set objContainer = GetObject("LDAP://odin/CN=Recipients,OU=Office,o=Acme") 'create a new distribution list Set objDL = objContainer.create("groupOfNames", "cn=Acctusers") 'Set distribution properties objDL.cn = "Accounting Users" 'display name objDL.uid = "Acctusers" 'alas objDL.mail = "Acctusers@acme.com" ' default SMTP address 'X.400 address objDL.textEncodedORaddress = _ "c=US;a= ;p=HeadOffice;o=Acme;s=Acctusers" objDL.SetInfo
The equivalent to a distribution list under Exchange 2000 is a mail-enabled group, which turns an Active Directory user group into a distribution list. Using CDOEXM, get a reference to the Active Directory group you want to enable and invoke the MailEnable method:
Dim objMember, objGroup 'get a reference to a group object list Set objGroup = _ GetObject("LDAP://cn=AG,cn=Users,dc=c3i,dc=com") objGroup.MailEnable objGroup.SetInfo
Discussion
Distribution lists allow the grouping of related recipients into lists. Distribution lists reside in the same containers as mailboxes.
To create a distribution list under Exchange 5.5, get a reference to the container you want to create the list in and create an object of groupOfNames type. The name of the distribution list is specified in RDN format:
' Set objContainer = _ GetObject("LDAP://odin/CN=Recipients,OU=office,O=Acme") Set objDL = objContainer.Create("groupOfNames", "cn=Acctusers")
Before the distribution list can be made active, the properties listed in Table 16-6 must be set.
PROPERTY |
DESCRIPTION |
---|---|
cn |
Friendly display name. |
Uid |
Distribution list unique identifier. |
TextEncodedORaddress |
X.400 address. Used for message routing. |
Once the Exchange 5.5 distribution has been created, you can add objects to it. To add an item to a distribution list, get a reference to a list and invoke the Add method. The syntax is as follows:
objDL.Add(strLDAPPath)
strLDAPPath is the full LDAP path to the object you want to add. You can add mailboxes, custom recipients, or other distribution lists.
'get a reference to an existing DL Set objDL = _ GetObject("LDAP://odin/cn=acctusers,cn=Recipients,ou=Office,o=Acme") 'add some mailboxes objDL.Add "LDAP://odin/cn=jsmith,cn=Recipients,ou=Office,o=Acme" objDL.Add "LDAP://odin/cn=joeb,cn=Recipients,ou=Office,o=Acme"
To delete an object from the list, invoke the Remove method on the distribution list object you want to remove an item from:
objDL.Remove(strLDAPPath)
strLDAPPath is the full LDAP path to the object you want to delete.
'get a reference to an existing DL Set objDL = _ GetObject("LDAP://odin/cn=acctusers,cn=Recipients,ou=Office,o=Acme") 'remove a mailbox objDL.Remove "LDAP://odin/cn=jsmith,cn=Recipients,ou=Office,o=Acme "
Active Directory groups are used as distribution lists (mail-enabled groups) under Exchange 2000. Use the CDOEXM MailEnable method to mail-enable a group. See Solution 14.13 for an example of how to create an Active Directory group. The second Solution script mail-enables the Power Users group.
See Also
Solution 14.13. For more information, read the MSDN Library article "Distribution List Manager Sample Code" (http://msdn.microsoft.com/library/en-us/exchserv/html/directry_231h.asp).
Enumerating a Distribution List
Problem
You want to enumerate a distribution list.
Solution
You can set a reference to the distribution list for which you want to enumerate and then iterate through the Members collection:
Dim objMember, objDL 'get a reference to a distribution list Set objDL = _ GetObject("LDAP://odin/cn=acctusers,cn=Recipients,ou=Office,o=Acme") For Each objMember In objDL.Members Wscript.Echo objMember.Name Next
The steps required to enumerate a distribution list under Exchange 2000 are pretty much the same as Exchange 5.5. Get a reference to the mail-enabled Active Directory group you want to enumerate and iterate the Members collection:
Dim objMember, objGroup 'get a reference to a group object list Set objGroup = _ GetObject("LDAP://cn=AG,cn=Users,dc=c3i,dc=com") 'enumerate the group objects For Each objMember In objGroup.Members If Not objMember.mailNickName = "" Then Wscript.Echo objMember.Name Else Wscript.Echo objMember.Name & "is not an Exchange enabled object" End If Next
Discussion
To enumerate a distribution list, get a reference to a list and iterate through the Members property. The objects returned from the Members property may be a mailbox, custom recipient, or distribution list type objects.
Because Exchange 2000 uses the Active Directory to store mail recipients, distribution lists may contain objects that are not mail-enabled. One way of determining non-mail-enabled objects is to check if the mailNickName property is empty, as is demonstrated in the second Solution script.
See Also
For more information, read the MSDN Library article "Enumerating Groups" (http://msdn.microsoft.com/library/en-us/wss/wss/_cdo_enumerating_groups.asp).
Creating a Recipients Container
Problem
You want to create an Exchange 5.5 recipients container or Exchange 2000 address list.
Solution
To create an Exchange 5.5 recipients container, get a reference to a container object you want to create the new container in. Create a new Container object, specifying an RDN name to identify the new container:
Dim objContainer, objNewContainer, objNewContainer2 Set objContainer = GetObject("LDAP://odin/OU=Office,O=Acme") 'create a root recipients container Set objNewContainer = objContainer.create("Container", "cn=External Users") objNewContainer.Put "Container-Info", &H80000001 objNewContainer.SetInfo 'nest a recipients container inside the new External users container Set objNewContainer2 = objNewContainer.create("Container", "cn=ABC Ltd") objNewContainer2.Put "Container-Info", &H80000001 objNewContainer2.SetInfo
For Exchange 2000, get a reference to the container that will list the address list and create an object of the addressBookContainer class:
Dim objAddressContainer, objNewAddressContainer 'get a reference to the container the recipient list will reside in... Set objAddressContainer = _ GetObject("LDAP://CN=All Address Lists," & _ "CN=Address Lists Container,CN=C3I,CN=Microsoft Exchange," & _ "CN=Services,CN=Configuration,DC=c3i,DC=com") 'create an object of addressBookContainer class, specifying the name 'using in RDN format Set objNewAddressContainer = _ objAddressContainer.Create("addressBookContainer", "CN=Company X") 'set display name objNewAddressContainer.DisplayName = "Company X List" objNewAddressContainer.instanceType = 4 'set the LDAP search criteria for the address list. The following criteria ' lists all contacts that are employees of Company XYZ objNewAddressContainer.purportedSearch = "(&(&(&(& (mailnickname=*)(|" & _ "(&(objectCategory=person)(objectClass=contact)))))" & _ "(objectCategory=user)(company=Company X)))" objNewAddressContainer.SetInfo
Discussion
Containers are used to organize recipients under Exchange 5.5 servers. Initially the Recipients container is the only area available to store mailboxes, but additional containers can be created to organize recipients.
The Container-Info property must be set to the hexadecimal value of &H80000001, which identifies the container as a mailbox recipients container.
Set the objNewContainer.Put "Container-Info", &H80000001
Recipients containers can be nested.
Recipients containers are referred to as address lists under Exchange 2000. While an address list is functionally equivalent to an Exchange 5.5 recipients container, they are implemented differently. Because the Active Directory contains the directory structure for Exchange 2000, there is no real need for a separately maintained directory as in earlier versions of Exchange server.
The tricky part of creating an Exchange 2000 address list is setting the search criteria through the purportedSearch property. This property determines what objects will appear in the address list based on search criteria using Lightweight Directory Access Protocol (LDAP) search criteria.
It is beyond the scope of this book to cover LDAP queries. Knowing how to build LDAP queries doesn't guarantee success setting the purportedSearch property, because Exchange 2000 requires a number of not-so-obvious properties to create enable function address list.
The easiest way to generate the LDAP queries is to use the Exchange 2000 System Manager to build a query and then copy and paste the query into code. To generate a query, follow these steps:
- Start Exchange 2000 System Manager.
- Select the address list you want to create a query for.
- Display the properties for the address list.
A dialog box similar to the one in Figure 16-4 appears.
Figure 16-4: Address list properties
Modify the address list query. Once you have built the query, copy the resulting LDAP query string into your code.
Deleting an Exchange Object
Problem
You want to delete an Exchange mailbox.
Solution
To delete an object from the Exchange 5.5 directory, get the container that contains the object you want to delete and invoke the Delete method:
'get a reference to a container to remove object from Set objContainer = _ GetObject("LDAP://odin/cn=Recipients,ou=Office,o=Acme" 'delete an object objContainer.Delete "organizationalPerson", "cn=freds"
For Exchange 2000, get the Active Directory user object you want to remove the mailbox for and invoke the DeleteMailbox method:
Set objUser = GetObject("LDAP://cn=Fred,cn=Users,dc=c3i,dc=com") objUser.DeleteMailbox objUser.SetInfo
Discussion
Any item in an Exchange 5.5 server, such as a mailbox or distribution list, can be deleted using the Delete method. The Delete method operates on the container object, so you must first get a reference to the container where the object is located.
Once you have the container, invoke the Delete method. The syntax is as follows:
objContainer.Delete strClassName, strObjectName
strClassName specifies the object class type to delete—for a user, the class name is user. strObjectName represents the user ID to delete. This is organizationalPerson for a mailbox.
Exchange 2000 is a bit different as a result of its reliance on Active Directory. CDOEXM exposes a DeleteMailbox method that deletes all Exchange resources associated with an Active Directory user. It does not delete the Active Directory user itself. See Solution 14.13 for information on deleting an Active Directory objects.
The DeleteMailbox method does not work on address lists or remote addresses under Exchange 2000. Because no real resources such as messages are stored with these objects, they simply need to be disabled. Use the CDOEXM object's MailDisable method to disable an address list or remote address:
'get a reference to the group object you want to disable Set objGroup = GetObject("LDAP://cn=AGROUP,cn=Users,dc=c3i,dc=com") objGroup.MailDisable objGroup.SetInfo
See Also
For more information, read the MSDN Library articles "Disabling a Mail Recipient" (http://msdn.microsoft.com/library/en-us/wss/wss/_cdo_disabling_a_mail_recipient.asp) and "Deleting a Mailbox" (http://msdn.microsoft.com/library/en-us/wss/wss/_cdo_deleting_a_mailbox.asp).
Searching an Exchange Server
Problem
You want to search all containers within an Exchange server.
Solution
You can create an ADO Connection object and set the provider to ADsDSOObject. Execute a query against the Exchange directory store using SQL to specify criteria for which objects to return.
The following example provides a generic function, ExecuteQuery, that can be used to execute Exchange 5.5:
'Exchange 2000 query ExecuteQuery "SELECT cn FROM "& _ "'LDAP://DC=acme,DC=com' WHERE" & _ "department='Accounting' AND objectCategory='person'" 'Exchange 5.5 query ExecuteQuery "SELECT cn,TelephoneNumber FROM "& _ "'LDAP://Odin' WHERE objectClass='organizationalPerson'" & _ "AND department='Accounting'" Sub ExecuteQuery(strQuery) Dim objConn, objRst Set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" 'execute a query against the Exchange server Odin, listing all mailboxes 'where the department is Accounting Set objRst = _ objConn.Execute(strQuery) 'loop through all mailboxes and output the display name Do While Not objRst.EOF Wscript.Echo objRst("cn") objRst.MoveNext Loop objRst.Close objConn.Close End Sub
Discussion
Searching parts of or the entire Exchange 5.5 or 2000 directory can be performed using the ADSI OLE DB provider. The steps required to initiate the ADO objects are the same for both versions of Exchange, the main difference being in how the source is specified.
Create an ADO Connection object and specify set the Provider property to ADsDSOObject. Open a connection by invoking the Connection object's Open method. The source here can be any string (something has to be passed) and it does not affect the Connection object.
Set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider"
Once the connection is open, you can execute queries against the Exchange directory. The query is in the form of a SQL query:
Set objRst = _ objConn.Execute("SELECT adspath,cn,name,objectClass FROM "& _ "'LDAP://odin'" & _ "WHERE objectClass='organizationalPerson'")
You must specify the exact fields you want to select. You cannot specify the SQL * operator to get all fields, because you may be querying different objects in the directory that don't expose the same properties as other objects returned by the query. Specifying the SQL * operator only returns one field, the ADsPath, which is the LDAP path to the object.
The query source specified after the FROM clause is the LDAP path to the container you want to start the search. In Exchange 5.5 the source is specified by the LDAP path to the Exchange server, while in Exchange 2000 it's the path.
There must be a WHERE criteria clause to identify what is to be returned. The WHERE criteria cannot be omitted, even if you want to search for all objects in the directory. If you want to process all objects in the directory, set the criteria to match at least one string property to *, which is a wildcard and will return all matches:
SELECT adspath,cn,name,objectClass FROM 'LDAP://odin' WHERE objectClass='*'
Any string criteria must be surrounded in single quotes.
You cannot update the results returned by the query. All ADSI recordset results are read-only. If you need to modify the results, use the ADsPath field for the result to get a reference to the Exchange object using GetObject and modify the object properties directly.
Some Exchange directory objects properties cannot be easily queried. For example, each mailbox or distribution list can have multiple secondary e-mail addresses. These are stored as an array, which cannot be referenced using criteria.
The following sample demonstrates how to update values for Exchange 5.5 mailboxes returned by an ADO ADSI query. The code returns all mailboxes for the accounting department. References are made to the mailbox object. All the e-mail addresses are searched, and if any contain the domain acme.com, they are replaced with accounting.acme.com:
Dim objConn, objRst, aMailBoxes, nPos, objMailbox, nF Set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" 'execute a query against the Exchange server Odin, listing all mailboxes 'where the department is Accounting Set objRst = _ objConn.Execute("SELECT ADsPath FROM "& _ "'LDAP://Odin" & _ "' WHERE objectClass='organizationalPerson' AND department='Accounting'") 'loop through all mailboxes and output the display name Do While Not objRst.EOF 'get the mailbox object from directory using the object path Set objMailbox = GetObject(objRst("ADsPath")) aMailBoxes = objMailbox.otherMailbox 'check if aMailBoxes returns an array of values If VarType(aMailBoxes) = 8204 Then 'loop through each E-mail address in array For nF = 0 To UBound(aMailBoxes) 'check if E-mail address contains Acme.com, if so ' replace with accounting.acme.com If StrComp(Right(aMailBoxes(nF), 9),"@acme.com",vbTextCompare) = 0 nPos = InStr(aMailBoxes(nF), "@acme.com") aMailBoxes(nF) = Left(aMailBoxes(nF), nPos-1) & "accounting.acme.com" objMailbox.Put "otherMailbox", aMailBoxes objMailbox.SetInfo End If Next End If objRst.MoveNext Loop objRst.Close objConn.Close
The following command-line script, exsearch.wsf, searches a specified Exchange server and returns all results that meet the specified criteria:
The command-line syntax is as follows:
exsearch.wsf server fields query
Server is the name of the Exchange server, and fields is a list of LDAP property names you want to return. The results are separated by commas. Query is a query expression containing the search criteria to execute against the specified server.
The following command line would return the cn,l and adspath values from the Exchange server Odin for all objects where the city is Vancouver and the department is Accounting:
exsearch.wsf odin cn,l,adspath "l='Vancouver' AND department='Accounting'"
Exchange 2000 information is stored in Active Directory under Windows 2000. When you search Exchange 2000, you are effectively searching Active Directory. Solution 14.6 provides a generic command-line script, adsiqry.wsf, that can execute queries against Active Directory.
See Also
Solution 14.16. For more information, read the MSDN Library articles "Distribution List Manager Sample Code" (http://msdn.microsoft.com/library/psdk/exchserv/directry_231h.htm) and "Searching with ActiveX Data Objects (ADO)" (http://msdn.microsoft.com/library/en-us/netdir/adsi/searching_with_activex_data_objects_ado.asp).