Copyright: 1992-1998


Microsoft Exchange Server Scripting and Routing

Using the Scripting Agent and Routing capabilities of Microsoft® Exchange Server version 5.5, you can turn a folder into an application, enabling it to run event-triggered server-side scripts and control the flow of messages, forms, or documents among recipients in your organization.

You can use the Microsoft Exchange Server Scripting Agent and Microsoft Exchange Server Routing independently of one another, though the Routing capabilities make use of underlying Scripting Agent technology.

This section describes both of these components:

•	Microsoft Exchange Server Scripting Agent

•	Microsoft Exchange Server Routing


Microsoft Exchange Server Scripting Agent

The Microsoft® Exchange Server Scripting Agent lets you use server-side scripts that run as a result of events occurring in folders. Such triggering events include timer events and actions such as posting, editing, or deleting a message. They can take place in private folders (mailboxes) or public folders. You need sufficient folder permissions to install and enable event-driven folder scripts.

You can write these scripts in Microsoft® Visual Basic® Scripting Edition (VBScript), JavaScript, or other supported scripting languages, and you can use Notepad (by default) or Microsoft® Visual Studio™ (specifically, the Microsoft® Developer Studio® IDE) as your script editor, in conjunction with Microsoft® Outlook™ version 8.03. See Writing and Installing Scripts.

Collaboration Data Objects (CDO, formerly Active Messaging) is the primary interface that scripts use to access and manipulate data in Microsoft Exchange information stores. (These scripts call CDO objects to perform their operations.)


Application Scenario: an Expense Report

A typical and appropriate use of server-event scripting is an approval application such as expense-report processing. In this example, a person wanting reimbursement fills out and submits a request in the form of an e-mail message. The simplest routing path takes the message to the requester's supervisor, to a person in Accounts Payable, and finally back to the requester, with payment notification.

This example shows that scripts can use information from a message, obtain information from other sources, and respond accordingly, which may include changing the path the message takes.

The employee submits an expense report by mailing or posting it to a designated "Expense Report" folder. Its arrival in the folder (known as the "application" folder) triggers the Folder_OnMessageCreated event.

The Folder_OnMessageCreated subroutine in the script evaluates the properties contained in the expense report and verifies that all the required ones are present. If any are missing, it returns the report to the sender.

This subroutine also evaluates the amount requested in the expense report. It can look up the name of the sender's manager in the directory and forward the report to that person automatically. Or it can look up the expense authorization budget limit and forward the report to the manager's manager if the limit would be exceeded. In this way, the subroutine can use server-side logic to perform directory lookups and make routing decisions based on properties of people in the directory.

If we assume that expense reports will not be edited while being processed, the script that processes them will not need a Message_OnChanged subroutine. But it will almost certainly need a Folder_OnTimer subroutine, which would be triggered if no response has arrived from the manager who received the request after a chosen number of days. The subroutine could, for example, notify the requester (or the manager's manager) of the delay and suggest that another action be taken.


At a Glance: Setting up the Event Service

Perform the following actions to install and configure the Microsoft Exchange Event Service.

To set up the Event Service

1.	While installing Microsoft Exchange Server (version 5.5 or later), your system administrator also installs the Microsoft Exchange Event Service. After the Event Service is installed, it will run automatically as a Microsoft® Windows NT® service when you start Microsoft Exchange Server. During installation, a folder (called EventConfig_<ServerName>) is automatically created in the information store. This folder holds information about the Event Service. You will use this folder in a later step when binding agents to the server.

2.	(Optional) Install Microsoft Visual Studio, to use as a script editor. Otherwise, Notepad is the default script editor.

3.	To configure Microsoft Visual Studio so that you can edit and save scripts for the Exchange Scripting Agent, refer to the Release Notes included with your installation compact disc of Microsoft Exchange Server version 5.5.

4.	Install Microsoft Outlook version 8.03 or later. (This is the version of Microsoft Outlook that you receive with Microsoft Exchange Server version 5.5.)

5.	Have a Microsoft Exchange Server administrator grant permissions. You need sufficient permissions to run scripts in folders. For more information, see Granting Permissions.

6.	Create an agent to monitor and respond to events in a folder. This involves writing and adding scripts to the folder, and binding agents to the computer running Microsoft Exchange Server, on which you want the scripts to run.

7.	(Optional) Advanced users can write a custom agent, instead of a script, to process events.


Scripting Architecture

The following elements work together to provide server-side event scripting and are depicted in the illustration that follows:

•	The Microsoft Exchange Event Service  A Microsoft® Windows NT® service that runs on the computer running Microsoft Exchange Server. Using Microsoft Outlook, you configure this service to monitor events that occur in folders you specify.

•	Folders  The folders upon which event scripting works can be Microsoft Exchange private folders (mailboxes) or public folders.

•	Microsoft Exchange Scripting Agent  An engine that processes scripts. This element is a Component Object Model (COM) object that exposes the IExchangeEventHandler interface.

•	User-created scripts  These scripts, which call CDO objects/interfaces, constitute the actual CDO logic that works on folders. Scripts are stored as messages in the folder and, as such, travel with the public folder application. These messages are visible only through the Agents interface or through a utility such as Mdbvu32.exe, and are hidden to Microsoft Exchange clients such as Microsoft Outlook.

Other related elements—not seen in the diagram—are these:

•	Microsoft Exchange Administrator program  A graphical interface used for configuring and maintaining the sites and servers of an organization, for creating and configuring public folders, and for granting permissions to users—such as for writing and enabling scripts.

•	Microsoft Outlook  Using Microsoft Outlook version 8.03 or later, you can create agents that respond to events in folders.


Advantages of Server-side Logic

Logic performed on the server enables the creation of many types of useful applications, including workflow applications. Workflow is improved in the following ways:

•	Exception handling  If a recipient of an expense report, for example, is away for several days without access to e-mail, the report would remain unread at that point in its path. When this happens, script logic executed on the server could automatically approve the item, reject it, or send it to the absent recipient's manager.

•	Routing determination  When the expense report (a message) is posted, the script can read message properties, determine where it should go next, and then update the state of the message.

•	State verification  If logic were implemented on the client, the workflow logic would travel with the message and would therefore reside only on individuals' computers. This would make it impossible to check its state (for example: which recipients have responded and which haven't) from a central location. A server-resident script could store and update state information on a server location—such as in the monitored folder—and thus always have access to it.

•	Data validation  An application may need to control the completeness and correctness of items submitted, such as making sure that required properties are present. This is done best when data-validation logic is consolidated in a server script. Then, no matter what form recipients use to post or edit a workflow item, server logic can validate its data. For example, it could check for a department number on an expense report and, if missing, return the message to the sender.

Implementing workflow logic client-side could work for some applications, but it still might require that the server perform time-out monitoring or that user workstations be logged on continuously. Because applications that need successive approval steps are typical, the server-side scripting provided by the Microsoft Exchange Scripting Agent is a more reliable and efficient method than using client-side logic.


Typical Steps in Event Processing

The following steps illustrate folder event processing and refer to elements in the diagram in Scripting Architecture. In this example, "Folder 3" is one of several folders configured to monitor events. The creation of the agents for this folder linked certain events that occur in Folder 3 to a script placed in Folder 3.

1.	A message is posted to Folder 3, a folder being monitored by the Microsoft Exchange Event Service.

2.	A notification of the posting is sent to the Event Service.

3.	The Event Service calls an Incremental Change Synchronization (ICS)method to request all the changes that have occurred in Folder 3 since the last time an event occurred in that folder. The Event Service translates the notification into an event.

4.	The Event Service keeps track of the agents registered for every type of folder event. Because the agent called Microsoft Exchange Agent Scripting has been registered for events in this folder, the Event Service instantiates an agent of this type.

5.	The Event Service calls the Run method on the IExchangeEventHandler interface on the agent. In doing so, it passes the folder identifier of Folder 3, the message identifier of the newly posted message, and the session object of the logged-in CDO session.

6.	The scripting agent obtains the script from the folder being monitored.

7.	The scripting agent creates a CDO session (with the Microsoft Exchange identity of the person who saved the script in Folder 3) and passes it to the script. Now, when performing actions within the system, the script has the same rights as its author. See Scripts, Agents, and Security.

8.	The scripting agent runs the script for the event that occurred.

Note − Synchronous versus Asynchronous Event Handling  The Microsoft Exchange Event Service fires events asynchronously with respect to the Microsoft Exchange information store. This means that the store does not block your event script, or wait for it to run, before letting other processes access the folder or message. Other processes (Inbox Assistant rules, or even a fast user) could move, copy, delete, or modify the message before your script has a chance to run.

The Microsoft Exchange Scripting Agent is therefore suitable for typical, medium-volume workflow or administrative applications. It is not suitable for applications that would, for example, scan every piece of mail in or out of the system for viruses, or archive every message for government record-keeping purposes, because there is no guarantee that your scripts will see every message. A good example is trying to use OnMessageCreated events in your Outbox folder to process all outgoing mail. By the time your script runs, the message will already have been delivered and deleted from your Outbox.

Additionally, some of these types of scripting applications could face problems of scale. Depending on the application's purpose, you would either have to manually install a script in every folder for every user, or the volume would simply be too high to process with an interpreted language like VBScript.


About ICS Notifications

Incremental Change Synchronization (ICS) is a reliable mechanism used for obtaining information about folder events. ICS acts as a bookmark, so that changes in folders are never missed, even if the Event Service is down. ICS is also efficient: only one notification is generated per changed document.


About Agents

An agent maps a folder, one or more events, and the code (usually in a script) that processes those events. There are two types of agents:

•	A script, combined with the Microsoft Exchange Scripting Agent and a folder in which events are monitored

•	Custom agents

An agent is like a rule in that it has these characteristics:

•	It is tied to a specific folder.

•	It runs when a certain event triggers it, such as when a message with specific properties appears in that folder.

•	It has specific behavior.

Agents differ from rules in that, while any Microsoft Exchange recipient can set a rule, you need special folder permissions to set up agents. For information on creating agents, see Configuring Events and Actions.

About the Microsoft Exchange Scripting Agent

The Microsoft Exchange Scripting Agent is an agent that runs folder-resident scripts and provides CDO session, folder, and message objects to the script. It can work in conjunction with Microsoft Transaction Server. This is the default agent installed as part of Microsoft Exchange setup.


Microsoft Exchange Server Administration

The Microsoft® Exchange Server administrator controls a number of aspects that affect event scripting:

•	Permissions on an agent's configuration folder  Administrators determine who (persons with Author permission on the EventConfig_<ServerName> folder) can bind agents to run on any particular server. See Granting Permissions and Binding an Agent to a Server.

•	Permissions on the application folder  Administrators grant permissions for authoring and running scripts within the folder in which events will be monitored. Without Owner permission on a folder, you can save a script into the folder, but you cannot create an agent using Microsoft Outlook because the option for doing so (the Agents tab in the folder property sheet) will be unavailable. If you create a folder, you automatically have Owner permission on it until your permissions are expressly changed.

•	Agent installation  Because administrators are in charge of the software installed on the server computer, they control which agents are available (installed) on the server.

•	Script restrictions  Administrators can set script restrictions, such as which COM objects are available, and the maximum time of execution.

For related information, see Chapter 6, "Configuring Public Folders," in the Microsoft Exchange Server Getting Started Guide.


Granting Permissions

In order to install a script on the server, you need correct permissions on two folders:

•	You must be an owner of the application folder—the folder in which events are monitored—in order to edit or save scripts there.

•	You must have Author or Owner permission on the folder in which agents are created. This permission is granted in the following steps, which are to be followed by a server administrator.

To grant permissions for installing scripts

1.	Using the Microsoft Exchange Server Administrator program, in the Systems Folder container under \Events Root, select the EventConfig_<ServerName> folder that corresponds to the server on which the Microsoft Exchange Event Service is running.

2.	On the File menu, choose Properties, and then choose Client Permissions.

3.	Choose Add, and then select the user who will have permission to run applications or other agents on this server.

4.	In the Roles dialog box, select Author or another role with greater permissions (Owner); take special care when granting Owner permission because of the power this role entails.

For related information, see the Microsoft Exchange Server Getting Started Guide.


Scripts, Agents, and Security

Because event scripting uses Microsoft Exchange objects, the level of Microsoft Exchange permissions for scripts is important. But because non-Microsoft Exchange objects can also be used, Microsoft Windows NT permissions are important as well. This section discusses both types of permissions.

The Microsoft Exchange Scripting Agent creates a CDO session based on the mailbox identity of the script author. This means that it has Microsoft Exchange Server permissions equal to those of the script author when accessing objects within the CDO session.

Typically, the Microsoft Exchange Scripting Agent runs on the Microsoft Exchange site service account, whose Windows NT permissions match those of basic Microsoft Exchange components such as the directory service and the information store. This means that the agent has the same broad powers on the system as Microsoft Exchange Server itself. The agent can, for example, open any recipient's mailbox. (In fact, it does open the mailbox of the script author, in order to determine that person's Microsoft Exchange Server identity.)

For this reason, unless you use Microsoft Transaction Server (MTS) as described in the following section, you should only allow trusted developers to create and bind scripts that run on your Microsoft Exchange Server computers. For information on granting permissions to run scripts on your servers, see Chapter 6, "Configuring Public Folders," in the Microsoft Exchange Server (version 5.5) Getting Started Guide.

Running Scripts with a Lower-Privilege Windows NT Account

See the Microsoft Exchange Server 5.5 Release Notes for details on how to use MTS as a process manager for running your scripts under a particular Windows NT security account (for example, as the IUSER_MACHINE account that is created for IIS anonymous logons). MTS is available as a component of Microsoft® Internet Information Server (IIS) version 4.0.


Configuring Events and Actions

Using Microsoft® Outlook™, a folder owner can create a script and configure the folder to monitor events that will trigger script functions. As mentioned previously, you must also have Author permission on the EventConfig_<ServerName> folder to bind agents on the server on which they will be run.

To create a script in a folder

1.	Start Microsoft Outlook and locate the folder whose events you want a script to respond to.

2.	Right-click this folder, or select Folder from the File menu.

3.	Select Properties for that folder. This displays the Expense Report Properties dialog box.

4.	Choose the Agents tab to display the Agents property page.

5.	Select New. This displays the New Agent dialog box.

6.	Give the agent a name, such as Process New Expense Report. This also renames the dialog box.

7.	Choose an event to be monitored. In the When the following event(s) occur check box, select, for example, A new item is posted in this folder. This is illustrated in Process New Expense Report Dialog Box. For more information about the other choices in this dialog box, see Scheduled Event Dialog Box, and About Event Logs.

8.	Choose an agent for the event. To use the default script agent, choose the Script option button and go to Step 8. If you intend to use a non-script agent, skip to Step 9.

9.	Choose Edit Script. This launches Notepad by default, or Microsoft® Visual InterDev™ if it is installed. If the script does not exist, a default script will open that contains stubs for four events; see Procedure for Editing Scripts. If a script exists, with the script editor open, choose Open on the File menu, and then open the existing script.

10.	If non-script agents are available, they are listed in the drop-down list box below Edit Script, the Other option button is available, and you can choose it to select one of these agents. This list box shows all the COM objects that support the IExchangeEventHandler interface and are bound to the specified server. If, for an agent, you choose a COM object that is also an ActiveX® control that requires properties to be set, you can choose the Properties button to set them in the Properties dialog box.


Expense Reports Properties Dialog Box

Folder owners use this property sheet to configure the Expense Reports public folder.

To create or edit agents, click the Agents tab. See Agents Property Page.


Agents Property Page

Folder owners use this property page to create a new agent. This page is also used for binding an agent to a server.

This property page is used to connect events, scripts, and servers. Collectively, these components are displayed as properties of an agent.

As with the Permissions page, this page is visible only to owners of the folder. When the folder owner clicks the Agents tab, the property page displays a list of agents, as shown in the illustration Agents Property Page (with Agents Displayed).

The Agents property page contains the following controls:

•	Agents for this folder  This is a list box control that uses the check box style. It lists the current agent messages installed in this folder, displaying the property PR_DISPLAY_NAME. Double-clicking one of the items in the list box is the same as choosing the Edit button.

•	New  Choosing New causes a new agent message to be created. See New Agent Dialog Box.

•	Copy  Use Copy to copy agent messages between folders.

•	Edit  Use the Edit button to modify the existing agent configuration data. See New Agent Dialog Box.

•	Delete  Choosing Delete deletes the current agent messages. Deletion then requires user confirmation.

•	Run these agents on this server  Use this control to bind an agent to a server. This is a drop-down list of servers on which the script should be run. It is populated from the list of folders that are under the NON_IPM public folder tree and whose name follows the format EVENTS_<server name>. One such folder exists for each server that has the Event Service installed. Each of these folders is created when the Event Service is installed on a particular computer.

The server choice defaults to the home MDB server of the current folder, assuming that this server has the Event Service installed. If the home MDB server does not have the Event Service installed (and thus has no corresponding EVENTS_<server name> folder), the choice defaults to the first server on the list. The list is sorted alphabetically.

The set of agents for a given folder must be guaranteed to run on only one server. This helps to ensure that the common set of ICS bookmarks for this folder (stored in the agent message in the folder) are manipulated by only a single server (ICS client).

Note  Microsoft Outlook 98 may not display the Agents property page even if you have sufficient permissions (see Granting Permissions) on both the folder being monitored and on the EventConfig_<ServerName> folder. If this happens, you can make the property page visible by performing the following steps: Using Microsoft Outlook 98, click Options on the Tools menu. Then, click the tab to open the Other property page. Click Advanced Options. On the Advanced Options dialog box, click the Add-in Manager button. On the Add-in Manager dialog box, check Server Scripting and click OK. Click OK to close the Advanced Options dialog box and click OK again to close the Options page.


Agents Property Page with Agents Displayed

If agents have already been created for this folder, they appear in the Agents for this folder control, as shown in the following illustration of the Expense Reports Properties dialog box.


New Agent Dialog Box

The following dialog box is displayed when you choose New or Edit on the Agents property page.

This dialog box has the following controls:

•	Agent Name  This is a text edit box through which the author can name the agent. The string entered is used as the PR_DISPLAY_NAME property of the agent message that is written to the folder.

•	When the following event(s) occurs  This is a check box-style list box that contains the following event-type choices:

A scheduled event occurs

A new item is posted in this folder

An item is changed in this folder

An item is deleted in this folder

If at least one event is checked in this list box, the agent specified in the Run the following action section will start when that event occurs. Otherwise, no events are monitored in this folder.

•	Schedule  This is available only if A scheduled event occurs is checked. Choosing the Schedule button displays the Scheduled Event dialog box, which you use to schedule timer events.

•	Logs  Choosing this button displays the last 32KB of log messages resulting from this particular event, in this particular folder. See About Event Logs.

•	Run the following action  These controls are used to edit the agent to be invoked when a matching event is triggered.

•	Script  Choosing this option button causes the agent to default to the Microsoft Exchange Scripting Agent that handles scripts.

•	Edit Script  Choosing this button starts Microsoft Notepad as your script editor. To use Microsoft Visual Studio 97 to edit scripts, refer to the Release Notes for Exchange Server version 5.5.

•	Other (option button)  Choosing this option button sets the agent to the one listed in the drop-down list box.

•	Other (drop-down list box)  This control displays the list of IExchangeEventSink-compatible objects installed on the server to which the script was bound on the Agents property page.

•	Properties  Choose Properties to configure the properties of a COM object (a custom agent). This requires that the actual DLL or EXE files be installed on the local client computer as well as the server, so that the normal ActiveX property pages can be displayed.

•	OK/Apply  Choosing OK or Apply registers your folder to be monitored by the Event Service so that your new agent is triggered when the event occurs. Specifically, this action

1.	Writes a message to the application folder. This hidden message contains the script, if the action chosen was to handle scripts with the Microsoft Exchange Scripting Agent. The script, now stored in the application folder, travels with the folder if it is moved.

2.	Writes an event-binding message to the EVENTS_<server name> hidden public folder. This message holds information for use by the Event Service, such as which folder to monitor (it contains the folder's identifier), the name of the server on which to run the action, the identifier of the script message to be run, and any needed COM object properties.


Scheduled Event Dialog Box

If A scheduled event occurs is checked in the New Agent dialog box, the Schedule button is enabled. Choosing it displays the Scheduled Event dialog box, which you use to schedule timer events.

These are some of the controls on this dialog box:

•	Hourly  When this option is selected, the At time control and the Mon through Sun check boxes are unavailable. Use the Every control to specify the time interval on which the timer event should fire. The maximum number of hours is 99, and the maximum number of minutes is 59. Events will only fire during the hours indicated by the Start and End controls. All Day is the default choice.

•	Daily  When this option is selected, the At time control and the Mon through Sun check boxes are unavailable. Choosing Daily causes the event to be fired once every day at the time specified with the At control. Because this choice specifies a particular time of day, when Daily is selected, the All Day, Start, and End controls are unavailable.

•	Weekly  When this option is selected, the Every control is unavailable. It causes the event to be fired at the time specified by the At control on each day of the week checked. Because this specifies a particular time of day, when Weekly is selected, the All Day, Start, and End controls are unavailable.


About Event Logs

Choosing the Logs button displays the most recent log messages resulting from this particular event, in this particular folder. These messages are stored as properties—along with your script—in the hidden message in the application folder. You can have your script write messages to this log by assigning string values to the Script.Response intrinsic object.

Log data is displayed in a simple list box control. By default, there is a maximum of 32K of log text that can be stored. There is no mechanism to clear the logs; they replace each other—first in, first out—when the 32KB limit is reached.


Process New Expense Report Dialog Box

You see the following dialog box after you have named the agent (Process New Expense Report) and selected an event (A new item is posted in this folder) to trigger the agent.

For information about the controls on this dialog box, see New Agent Dialog Box.


Binding an Agent to a Server

One server running the Microsoft Exchange Event Service can handle events for an arbitrary number of folders. Although the Event Service can be running on any number of computers, a script runs only once per event, and each event (and thus each script) is processed by only a single server. Therefore, binding an agent to a server means choosing which Event Service server will run the agent.

For example, to monitor a given folder for new postings, you first specify a Microsoft Exchange server on which to run the events these postings will trigger.

You use Microsoft Outlook to perform the binding, and you do this while creating agents. Use the Run these agents on this server control on the Agents property page to bind an agent to a server. All the agents for a given folder must be bound to the same server.

Note  You can also bind agents to servers programmatically. See Binding Agents Programmatically.

Location of Servers, Folders, Scripts, and Registration Information

A folder on which you want to run a script may be anywhere, such as in a recipient's mailbox, or replicated from a folder on another server.

Binding information is stored in a public folder that represents a server on which the Event Service is running. Specifically, when an administrator installs the Event Service, a new folder is created in the non-IPM subtree of the information store, under System Folders\Events Root\. This new folder is named EventConfig_<ServerName>, and it exists to contain data that connects folder events to this particular server. The location of this folder is shown in the following illustration.

If, for example, you configure an event in a given folder to trigger an action that will be run on the server EXCHNGE3, the act of binding writes agent data into the folder EventConfig_EXCHNGE3. Although this folder contains binding data, it is not visible through the Microsoft Exchange Server Administrator program.

The public folder information store, the Event Service, and the agents can each be on different Microsoft® Windows NT® servers or all on the same server.

Permissions Are Needed to Bind Agents

The Microsoft Exchange administrator, who configures public folders, controls who is allowed to run scripts on a given server. Administrators must grant you Editor permission for you to bind an agent to be run on a particular server.

To continue with the example from the previous section, only people who have write permissions on the monitored folder for the server EXCHNGE3 can cause agents (including scripts) in that folder to be run on the server EXCHNGE3. Like all public folders, the property sheets for the folder EventConfig_EXCHNGE3 contain a Client Permissions property page. A Microsoft Exchange administrator can, on this page, assign Editor permission to whoever should be able to run agents on the server—in this case, EXCHNGE3.


Binding Agents Programmatically

It is possible to programmatically create and register agents (event bindings) on a Microsoft Exchange Server version 5.5 computer. Authoring tools built with Microsoft Exchange Server routing objects require this capability in order to register the routing engine as an event handler for a particular folder.

To create a binding programmatically, use the objects shown in the following table, Object Hierarchy for Event Bindings. For an illustration of one way to create bindings, see Sample Code: Enabling a Folder for Routing.


Object Hierarchy for Event Bindings

For more information about an individual object and its properties and methods, click the object's name in the following table.

Events

          Session

          BoundFolder

                    Bindings collection

                              EventBinding

                                        Handler

                                        Schedule

          EventBinding

                    Handler

                    Schedule

          Hosts collection

                    Host

                              BoundFolders collection

                                        Item

                                        Bindings collection

                                                  EventBinding

                                                            Handler

                                                            Schedule

                              Handlers collection

                                        Handler


Session

The Session object is the MAPI session that this Events object works with. You need to store a reference to this object, using the Set keyword, before taking any other actions. For example:

Set MAPISession = CreateObject("MAPI.Session")

MAPISession.Logon

Events.Session = MAPISession

You can see the session object used in a similar way in Sample Code: Enabling a Folder for Routing.


Item

An Item is a standard part of a collection. It lets you get a member of a collection (in this case, the BoundFolders collection) by a VARIANT rather than by enumeration.


Events

Events is the only top-level object in the Microsoft Exchange Event Configuration Library (ESCONF.DLL); this library is registered on your system when you install the Microsoft Exchange Server event service. Before working with any other event interfaces, you must first create an Events object and associate it with the current CDO session.

Property	Type	Access
BoundFolder	BoundFolder [VARIANT] (VARIANT varFolder, INT32 fCreate)	Read-only
EventBinding	EventBinding [VARIANT] (STRING strID) Note: Reserved for internal use.	Read-only
Hosts	Hosts [VARIANT]	Read-only
Options	Options [UINT32] Note: Reserved for internal use.	Read/write
Session	Session [UNKNOWN]	Read/write
Methods	Parameters
MoveBoundFolder	VOID MoveBoundFolder (STRING bstrHostName, VARIANT varBoundFolder)


BoundFolder

Property	Type	Access
Access	Access [UINT32]	Read-only
Bindings	Bindings [VARIANT]	Read-only
EntryID	EntryID [STRING]	Read-only
EntryID2	EntryID2 [STRING]	Read-only
EventMask	EventMask [UINT32]	Read-only
HostName	HostName [STRING]	Read-only
MDBEntryID	MDBEntryID [STRING]	Read-only
ScheduleCount	ScheduleCount [UINT32]	Read-only
Methods	Parameters
SaveChanges	VOID SaveChanges ()


BoundFolders

Property	Type	Access
Count	Count [INT32]	Read-only
Item	Item [VARIANT] (VARIANT varIndex)	Read-only


EventBinding

Property	Type	Access
Access	Access [UINT32]	Read-only
Active	Active [INT32]	Read/write
CreationTime	CreationTime [VARIANT]	Read-only
CustomProperty	CustomProperty [VARIANT] (VARIANT varPropId)  Note: Reserved for internal use.	Read/write
EntryID	EntryID [STRING]	Read-only
EntryID2	EntryID2 [STRING]  Note: Reserved for internal use.	Read-only
EntryID3	EntryID3 [STRING] Note: Reserved for internal use.	Read-only
EventMask	EventMask [UINT32]	Read/write
Handler	Handler [VARIANT]	Write-only
HandlerClassID	HandlerClassID [STRING]	Read/write
Name	Name [STRING]	Read/write
Priority	Priority [UINT32]  Note: Reserved for internal use.	Read/write
Schedule	Schedule [VARIANT]	Read-only
Methods	Parameters
SaveChanges	VOID SaveChanges ()
SaveCustomChanges	VOID SaveCustomChanges (VARIANT varMAPIOBJECT)


Bindings

Property	Type	Access
Item	Item [VARIANT] (VARIANT varIndex)	Read-only
Count	Count [INT32]	Read-only
Methods	Parameters
Add	VARIANT Add ()
Clone	VARIANT Clone (VARIANT varItem)
Delete	VOID Delete (VARIANT varItem)


Handler

Property	Type	Access
ClassID	ClassID [STRING]	Read-only
Name	Name [STRING]	Read-only
Methods	Parameters
(none)


Handlers

Property	Type	Access
Count	Count [INT32]	Read-only
Item	Item [VARIANT] (VARIANT varIndex)	Read-only
Methods	Parameters
(none)


Host

Property	Type	Access
BoundFolders	BoundFolders [VARIANT]	Read-only
Handlers	Handlers [VARIANT]	Read-only
Name	Name [STRING]	Read-only
Methods	Parameters
(none)


Hosts

Property	Type	Access
Count	Count [INT32]	Read-only
Item	Item [VARIANT] (VARIANT varIndex)	Read-only
Methods	Parameters
(none)


Schedule

Property	Type	Access
At	At [DATE]	Read/Write
Bitmap	Bitmap [VARIANT] Note: Reserved for internal use.	Read-only
Days	Days [UINT32]	Read/Write
EndTime	EndTime [DATE]	Read/Write
Interval	Interval [UINT32]	Read/Write
StartTime	StartTime [DATE]	Read/Write
Type	Type [UINT32]	Read/Write
Methods	Parameters
Clear	VOID Clear ()


Sample Code: Enabling a Folder for Routing

The following is a simple example using Microsoft® Visual Basic® that illustrates how to make a folder routing-enabled. It creates and enables a new event binding for the routing engine in the current Inbox, and installs both a simple Map and the default VBScript actions (see Script Actions) onto that Binding message.

At a more detailed level, this code performs the following steps:

1. 	Create a Session object (MAPI.Session) and log on to a MAPI session.

2. 	Create an Events object (MSExchange.Events).

3. 	Get the folder to be monitored (in the comment, the "event bindings folder associated with the current Inbox").

4. 	Check for existing event bindings in the folder to be monitored, and if none exist, create one.

5. 	Open the (hidden) message in which the event-binding information is stored.

6. 	Read the script actions provided in the Routing.vbs file into a string and store them in a PR_EVENT_SCRIPT property.  (The Routing.vbs file is currently available on the web at http://www.microsoft.com/exchange/appfarm.)

7. 	Create and populate a Map object (ExRt.Map).  Save it on the hidden event-binding message.  This example uses a function called MakeRow to help assemble individual lines in the Map object.

8. 	Commit changes and cleanup.

For clarity the example omits most error handling. For example, it installs the event binding only if no other event bindings exist in the folder.

Const PR_EVENT_SCRIPT = &H7102001E

Const SCRIPT_LOCATION = "D:\SRC\ROUTING\ROUTING.VBS"

Dim oSession, oEvents, oMessage As Object

Dim oBindings, oBinding, oBoundFolder, oMap As Object

Set oSession = CreateObject("MAPI.Session")

oSession.logon

Set oEvents = CreateObject("MSExchange.Events")

oEvents.Session = oSession

' Get the event bindings folder associated with the current Inbox

Set oBoundFolder = oEvents.BoundFolder(oSession.Inbox, True)

Set oBindings = oBoundFolder.Bindings

If oBindings.Count > 0 Then

    MsgBox ("Existing Agents in this Folder. Press OK to quit.")

    Set oEvents = Nothing

    oSession.logoff

    End

Else

    Set oBinding = oBindings.Add

    oBinding.Name = "Routing Objects Sample"

    oBinding.Active = True

    oBinding.EventMask = 1 + 2 + 4 + 8

    oBinding.HandlerClassID = "{69E64151-B371-11D0-BCD9-00AA00C1AB1C}"

    oBinding.SaveChanges

End If

' Get the (hidden) message associated with this event binding,

' so we can put some properties on it.

Set oMessage = oSession.Getmessage(oBinding.EntryID, Null)

' Read the standard script actions from the file ROUTING.VBS

Open SCRIPT_LOCATION For Input As #1

bstrEventScript = Input$(LOF(1), #1)

Close #1

' Store the script actions in PR_EVENT_SCRIPT

oMessage.Fields.Item(PR_EVENT_SCRIPT) = bstrEventScript

oMessage.Update

' Create a Map object and open it for read/write

Set oMap = CreateObject("ExRt.Map")

' Fill up the Map object with rows of activities

'  (The MakeRow function is defined below)

oMap.InsertActivity -1,  _

  MakeRow( 1, "Send", 2, Array("Jane Smith", False, "Please review …", "<ATTACH>", False, False) , 6 )

oMap.InsertActivity -1, MakeRow( 2, "Wait", 0, Array(10080), 1)

' Save the map into the hidden message object

oMap.SaveMap oMessage

' Note: must "dirty" the message by changing some property before

' calling update

oMessage.Subject = "Routing Object Samples"

oMessage.Update

'  Must call SaveCustomChanges on the Binding object since we modified

' custom properties on the event binding message.  The message object

' is the argument

oBinding.SaveCustomChanges oMessage

' Commit changes to any bindings we've modified in this folder

oBoundFolder.SaveChanges

' Clean up

Set oEvents = Nothing

oSession.logoff

'======================================================

' The MakeRow function creates an "ExRt.Row" object and populates

'  its properties with information passed as arguments to the

'   function.  It then returns the new object

'

' Function MakeRow (

'       Id     -> Row ID (numeric)

'       Action -> Row Action (string)

'       Flags  -> Action Flag (numeric)

'                                0= engine intrinsic

'                                2=script routine

'       Argv   -> Action arguments (array)

'       Argc   -> Number of elements in argv (numeric)

'  )

'  Returns the created Row object (ExRt.Row)

'======================================================

Function MakeRow ( ID, Action, Flags, Argv, Argc )

Dim RTRow

Set RTRow = CreateObject("ExRt.Row")

RTRow.ActivityID = ID

RTRow.Action     = Action

RTRow.Flags      = Flags

 	If Argc > 0 Then

         RTRow.SetArgs Argc, Argv

    	End If

' Return the object

Set MakeRow = RTRow

End Function


Writing and Installing Scripts

You can write scripts in VBScript, JavaScript, or another supported scripting language. You can use any script or text editor, including Microsoft Outlook version 8.03, and either Notepad or Microsoft Visual Studio 97. In fact, with a macro extension (an Add-In) installed, Microsoft Visual Studio can be used as a complete script creation tool. It lets you open, edit, and save scripts in folders within Microsoft Exchange information stores.

For details on configuring Microsoft Visual Studio to open, edit, and save scripts for use by the Microsoft Exchange Scripting Agent, please see the Release Notes for Microsoft Exchange Server version 5.5.


Using the Microsoft Script Debugger

To debug scripts that are running in the Microsoft Exchange Scripting Agent, you can use the Microsoft Script Debugger, which is available with Microsoft® Internet Information Server (IIS) version 4.0 or Microsoft® Internet Explorer version 4.0. Because the Script Debugger is not included as part of Microsoft Exchange Server, you must install one of these other products. During installation, choose the Custom installation option and then select the Microsoft Script Debugger option.

The Microsoft Script Debugger performs only local debugging. Therefore, you must run the debugger on the computer on which the script is executing. In the case of the Microsoft Exchange Scripting Agent, this is the Microsoft Exchange Server computer on which the script is executing.

To force your script to hit a breakpoint and start the debugger, insert the following command into your script, under the event subroutine you wish to debug:

•	For VBScript, this command is stop.

•	For JavaScript, the command is debugger.

To use the Microsoft Script Debugger to step into Event Service code, you must first log on with the same Windows NT service account as the Microsoft Exchange Event Service itself; otherwise, the debugger will not be launched correctly when it reaches a stop (or debugger) statement in the code.

As soon as an event occurs that triggers your script's event subroutine, the script will halt, and you will see the currently running script in the debugger window at the line containing the stop or debugger statement. Inside the script debugger, you can step into or around statements and you can inspect the values of variables by using the immediate command window. See the documentation on Microsoft Script Debugger for more information on using this tool.


Writing a Script

Scripts used with the Microsoft Exchange Event Service primarily use CDO, although they exhibit some differences from pure CDO scripts. For example, the following points are good to remember:

•	You do not need to write code to log on to a CDO session, because you will be passed the named value EventDetails.Session as an intrinsic object.

•	You can write "asserts" or other debugging strings to the Agent's execution log by assigning the string as value to the intrinsic object Script.Response.


Intrinsic Objects

The Microsoft Exchange Event Service passes the following intrinsic objects when your script is run:

•	EventDetails.Session  The object that represents the CDO session you're logged on as. Because a script is handed this logged-in CDO session, it automatically has access to all CDO objects. This session is logged on as the script author.

•	EventDetails.FolderID  The entry identifier of the folder in which the event took place.

•	EventDetails.MessageID  This is the identifier of the triggering message, if a message (and not a timer event) triggered the event.


Procedure for Editing Scripts

Using Microsoft Outlook, choose New Event, and then Edit Script. This creates a stub script that contains these empty subroutines:

•	Folder_OnMessageCreated

•	Message_OnChanged

•	Folder_OnMessageDeleted

•	Folder_OnTimer

(The preceding names are for VBScript. The corresponding JavaScript names are Folder::OnMessageCreated, Message::OnChanged, Folder::OnMessageDeleted, and Folder::OnTimer.)

You can add scripting code to any of these subroutine sections to control its functionality. To indicate that the script should not respond to an event of that type, just leave a section blank, or delete the section. Although this script could be written to respond to events of all four types, you could also choose to use separate scripts for each event.

Note: Using VBScript and JavaScript  You can write a script in pure VBScript, pure JavaScript, or a mixture of the two. If you mix the two languages and you are making cross-language calls, you need to prefix variable names with the name of the language; for example, VBScript.MyVar or JavaScript.MyVar.


Editing Agents' Properties

You can have your script change the behavior of your agent in any of several ways. The script can, for example:

•	Change the events the agent fires on.

•	Edit the details of a schedule (for scheduled events).

•	Implement filtering.

•	Implement error logging.

•	Return assert and response strings (example: "now at line 27") for debugging purposes (using the command Script.Response=<string>).


The Sample Script OSPREV.VBS

The following sample script ships with Microsoft Exchange Server version 5.5 and above. It contains the four basic functions Folder_OnMessageCreated, Message_OnChange, Folder_OnMessageDeleted, and Folder_OnTimer.

Each of these event functions calls two support functions: first GetEventDetails, and then MakeResponseMessage, as described in the following sections.

The GetEventDetails Function

In addition to error checking, the function GetEventDetails performs the following steps:

1.	Using the CDO session, it establishes the location of the current user's Microsoft Exchange mailbox. It does this with the call
Set AMSession = EventDetails.Session.

2.	It retrieves the user's Outbox with the call
Set fldrOutbox = AMSession.Outbox.

3.	Using the EventDetails object passed by the Microsoft Exchange Event Service, this function sets an application folder ("target" folder) to be the same as the monitored folder in which the event occurred. It does this with the assignments
idTargetFolder = EventDetails.FolderID and
Set fldrTarget = AMSession.GetFolder( idTargetFolder, Null ).

4.	This function also sets a target message to be the same as the message that triggered the event. It does this with the assignments
idTargetMessage = EventDetails.MessageID and
Set msgTarget = AMSession.GetMessage( idTargetMessage, Null ).

The MakeResponseMessage Function

In addition to error checking, the function MakeResponseMessage prepares and sends a response message that reports the number of messages in the monitored folder. For this, it uses the CDO response object in the call msgResponse.Send.

Script Text: OSPREV.VBS

<SCRIPT RunAt=Server Language=VBScript>

'---------------------------------------------------------------------

'FILE DESCRIPTION: Sample Exchange Server Event Script for Osmium

'

' Copyright (c) Microsoft Corporation 1993-1997. All rights reserved.

'---------------------------------------------------------------------

Option Explicit

'---------------------------------------------------------------------

' Localized strings

'---------------------------------------------------------------------

' Put all localizable strings and constants here

'---------------------------------------------------------------------

' Global Variables

'---------------------------------------------------------------------

Dim AMSession

Dim fldrOutbox

Dim msgTarget

Dim fldrTarget

'---------------------------------------------------------------------

' Event Handlers

'---------------------------------------------------------------------

' DESCRIPTION: This event is fired when a new message is added to the folder

Public Sub Folder_OnMessageCreated

On Error Resume Next

GetEventDetails

If Err.Number = 0 Then

MakeResponseMessage "A message has been added"

Else

Script.Response = "GetEventDetails Failed"

End If

End Sub

' DESCRIPTION: This event is fired when a message in the folder is changed

Public Sub Message_OnChange

On Error Resume Next

GetEventDetails

If Err.Number = 0 Then

MakeResponseMessage "A message has been changed"

Else

Script.Response = "GetEventDetails Failed"

End If

End Sub

' DESCRIPTION: This event is fired when a message is deleted from the folder

Public Sub Folder_OnMessageDeleted

On Error Resume Next

End Sub

' DESCRIPTION: This event is fired when the timer on the folder expires

Public Sub Folder_OnTimer

On Error Resume Next

End Sub

'---------------------------------------------------------------------

' Support Functions

'---------------------------------------------------------------------

' DESCRIPTION: Get the details of the event that fired

Private Sub GetEventDetails

On Error Resume Next

Dim oStores

Dim Temp

Dim idTargetFolder

Dim idTargetMessage

idTargetFolder = EventDetails.FolderID

idTargetMessage = EventDetails.MessageID

' some of the above may not exist

Err.Clear

Set AMSession = EventDetails.Session

If Err.Number = 0 Then

' We will send a msg, so let's get the Outbox here

Set fldrOutbox = AMSession.Outbox

If Err.Number = 0 Then

Set fldrTarget = AMSession.GetFolder( idTargetFolder, Null )

If Err.Number = 0 Then

Set msgTarget = AMSession.GetMessage( idTargetMessage, Null )

If Not Err.Number = 0 Then

Script.Response = "Session.GetMessage Failed: " & Err.Description

End If

Else

Script.Response = "Session.GetFolder Failed: " & Err.Description

End If

Else

Script.Response = "Session.InfoStores Failed: " & Err.Description

End If

Else

Script.Response = "Outbox.Messages Failed: " & Err.Description

End If

Else

Script.Response = "EventDetails.Session Failed: " & Err.Description

End If

End Sub

' DESCRIPTION: Make a response message

Private Sub MakeResponseMessage(strSubj)

Dim msgResponse

Dim iMsgCount

On Error Resume Next

iMsgCount = fldrTarget.Messages.Count

If Err.Number = 0 Then

Set msgResponse = fldrOutbox.Messages.Add( strSubj, "There are now " & iMsgCount & " messages in the folder")

If Err.Number = 0 Then

msgResponse.Recipients.Add "", "", 1, msgTarget.Sender.ID

If Err.Number = 0 Then

msgResponse.Recipients.Resolve(False)

If msgResponse.Recipients.Resolved = True Then

msgResponse.Send

If Not Err.Number = 0 Then

Script.Response = "Message.Send Failed: " & Err.Description

End If

Else

Script.Response = "Recipients.Resolve Failed: " & Err.Description

End If

Else

Script.Response = "Recipients.Add Failed: " & Err.Description

End If

Else

Script.Response = "Messages.Add Failed: " & Err.Description

End If

Else

Script.Response = "Messages.Count Failed: " & Err.Description

End If

End Sub

</SCRIPT>


Advanced Topics: Custom Agents

In the standard scenario of running an agent in a monitored public folder, an agent in that folder is routed by default to the script handler supplied by Microsoft® Exchange Server (the Microsoft Exchange Scripting Handler). But you may feel that scripting doesn't give fast enough performance, so you may want to use another handler in which event response code is hard-coded in C/C++. Or you may not want customers to see your source code, so instead of shipping scripts, you ship compiled code in binary format.

An agent that uses such a mechanism would probably contain no script, though it does contain some agent configuration data.

One example of a custom agent for a folder is the routing engine used to provide the functionality of Microsoft Exchange Server routing.


About Other Handlers

A handler is any COM object that exposes (implements) the IExchangeEventHandler interface and advertises (is registered under) the COM category CATID_ExchangeEventSink.

Other types of handlers could include those that can run Microsoft Visual Basic version 5.0 programs, JavaScript, Java VM code, and C++ code in addition to JScript or VBScript provided by Microsoft. Handlers can currently only be authored in C/C++.

The mechanism for processing folder events with custom handlers is similar to that used with the Microsoft Exchange Scripting Handler, as shown in the following diagram.


Invoking a Custom Agent

The following steps illustrate folder event processing and refer to elements in the diagram in the previous section. In this example, "Folder 3" is one of several folders configured to monitor events. The creation of the agents for this folder linked certain events that occur in Folder 3 to a script placed in Folder 3.

Although the usual case when an event occurs is for a script to be run, custom agents can also be used. This is because The Microsoft Exchange Event Service can pass an event to any agent that exposes the COM interface IExchangeEventHandler.

1.	A message is posted to Folder 3, a folder being monitored by the Event Service.

2.	A notification of the posting is sent to the Event Service.

3.	The Event Service calls an Incremental Change Synchronization (ICS) method to request all the changes to Folder 3 that have occurred since the last time an event occurred in that folder.

4.	ICS generates and sends the change list to the Event Service. This list contains the message identifier of the message just posted and any other changed messages—including new, changed, and deleted messages.

5.	The Event Service searches the monitored folder for agents.

6.	The Event Service requests the agent for the CLSID of its handler.

7.	The Event Service calls CoCreateInstance to create an object of that CLSID.

8.	The Event Service performs a QueryInterface for the IExchangeEventHandler interface.

9.	Once the Event Service has retrieved the IExchangeEventHandler interface on the object, it writes session, folder, and message information into properties in a Microsoft Exchange IEventSource object. The Event Service also sets the event type (new message, changed message, deleted message, timer event) in a property on the IEventSource object.

10.	The Event Service calls IExchangeEventHandler::ExecuteEvent, passing the IEventSource object.

11.	Using the IEventSource object passed from the Event Service, the custom handler responds to the folder event.


Programming Recommendations

Consider the following recommendations when designing a custom agent.

•	Be careful with security, because the MAPI session that you're passed has powerful permissions within Microsoft Exchange Server. Be particularly careful when handing control to another element in the system, especially if you are not the creator of that other element.

•	The EventSource object is provided by Microsoft, so to use it, all you need are the proper header files.

•	Do your own exception handling by watching out for exceptions and access violations.


Caching Sessions and Scripts

Your handler's design depends in part on the number of folders it will be used in and the workload (number, or volume, of events) it will carry within a folder. One affected design element is whether to cache a CDO session and a script. Consider the following cases:

•	Few folders, high volume per folder  For example, an agent functioning as a distribution list could broadcast any item posted to the monitored folder to the members of the list. Caching the members of the list could help in this example since list membership is not likely to change as often as messages are being posted.

•	Many folders, low volume per folder  Caching would be less helpful in this case.

•	Many folders, high volume per folder  An example of this case is a script agent used in many folders on a server; This case could occur, for example, when many of a system's recipients use script agents in folders within their private mailboxes. Caching information specific to each mailbox would probably help in this case.

In general, caching is more likely to help if high volume is involved.

In the case of the Microsoft Exchange Scripting Handler, if a new CDO session (which includes a logon to MAPI) had to be created every time a script fired, performance would suffer greatly. In this case, the session object (using the mailbox of the script author) is cached, which helps greatly. In other words, if a new script is run whose author also created another recently run script, that person's CDO session, having been cached, is reused. The script itself is also cached, to be used when the next event triggers it.

CDO Sessions and MAPI Sessions

The session that is passed to you is a MAPI session from the service, not a CDO session. This precludes Microsoft Visual Basic handlers from using it, because Visual Basic can only manipulate the IDispatch interface, an interface that MAPI does not support.

If your custom agent is written in Microsoft Visual Basic, it will need to perform its own CDO session logon.


Registering a COM Object as an Agent

In addition to the normal registration of your COM object you need to put the following information into the registry:

HKEY_CURRENT_USER \ CLSID \ {Your CLSID} \ Implemented Categories \ {50F45350-D0AF-11d0-9836-00AA006D27AB}

(Default Value) = 'Exchange Event Handler Category'


About the IExchangeEventHandler Interface

Every agent must implement the IExchangeEventHandler interface in its object. This interface has one method:

ExecuteEvent( IDispatch* pEventSource)

An EventSource is a COM object that exposes one interface: IEventSource. It has no methods, just the following properties:

Property	Description
Source	MAPI object (the agent message in the target folder)
SourceID	Entry identifier of the agent message in the EventConfig_<ServerName> folder
MessageID	Entry identifier of the message that was changed, added, or deleted (NULL for timer events)
Session	The MAPI session passed from the Microsoft Exchange Event Service
EventType	The type of event that occurred (an integer enumeration: 0, 1, 2, or 3)
MaxExecutionTime	Seconds of execution from beginning of agent execution until agent execution is terminated.
Response	Put a string here to record the outcome of the agent's execution. The string is written to the event log. The Response property is a variant, but the Event Service expects a string (if not a string, it will be ignored).


Administrators Set Up Handlers

If you write and distribute your own custom handler or buy a third-party handler for your own system, it's likely that a setup program will be distributed. If not, the agent must be registered manually, and its files copied. In either case, a server administrator is the person to set up the agent.

Similarly, if you're a folder author and you want to install a new agent that uses the handler you've written, you need to request that your server administrator install your handler.

For more information about administrators' roles, see Microsoft Exchange Server Administration and the Microsoft Exchange Server Getting Started Guide.


Security with Custom Handlers

You may want to limit the power of your custom handler. To do this, you can incorporate code that diminishes its power by, for example, impersonating a Microsoft® Windows NT® account that has fewer permissions.

One way to accomplish this is to implement your handler (COM object) as a Microsoft Transaction Server (MTS) object. In addition to providing support for database transactions, MTS also can act as a process manager for in-process COM objects. You can use MTS to specify that your object is always to run under a specific Windows NT security account − one that has sufficiently low privileges for your application.


Microsoft Exchange Server Routing

Microsoft® Exchange® Server Routing is a set of tools that simplifies the development of e-mail-based routing and approval applications. It contains three main components:

•	Routing engine  This COM component runs on the Event Service (see Scripting Architecture) on Microsoft Exchange Server version 5.5. It acts as a simple state engine that executes and tracks multiple process instances within a Microsoft Exchange folder. The state is advanced when events fire within the folder. The routing engine supports the execution of flow-control activities directly, and it can call Microsoft® Visual Basic® Scripting Edition (VBScript) functions for other activities. Microsoft Exchange Server Routing also works with the Microsoft Transaction Server (MTS); see Scripts, Agents, and Security and Security with Custom Handlers.

•	Routing objects  These COM objects are used to program the routing engine's behavior. These objects allow the creation and manipulation of process maps, which define the series of states to be tracked by the routing engine and the activities to be performed at each step.

•	VBScript actions  These are a default set of common VBScript functions for routing. They include functional activities such as Send, Receive, and Consolidate as well as evaluation activities such as IsTimeout and IsNDR. Developers can extend these activities with custom script functions as their application needs dictate.

Using these components, developers can create applications such as simple process designers, which allow users to define and create the steps in routing/approval application. An example of such a program, the Microsoft Exchange Routing Wizard, is included with Microsoft Exchange 5.5 routing objects as a sample application.

Setting up Microsoft Exchange Routing

Microsoft Exchange Server version 5.5, Service Pack 1 (SP1) includes the components used for routing. During the installation of SP1, the routing engine and the routing objects are installed to the server automatically if the requisite Microsoft Exchange Scripting Agent is present.


System Requirements for Routing

For Microsoft Exchange Routing, you need the following software installed:

•	Microsoft® Windows NT® Server 4.0 Service Pack 3, Intel or Alpha version

•	Microsoft Exchange Server 5.5, Service Pack 1

•	Microsoft Exchange Event Service

For the Routing Wizard sample, you need the following software installed:

•	Microsoft® Windows® 95 or Microsoft Windows NT (on an Intel computer)

•	Microsoft® Outlook™ 97 (version 8.03 or later, including Microsoft Outlook 98)

Caution  Installing versions of Microsoft Outlook 97 older than 8.03 on a Microsoft Exchange Server computer can cause incorrect registration of some system files. Please see KnowledgeBase article Q176744 at http://support.microsoft.com/support/kb/articles/q176/7/44.asp for more details.


Routing Overview

Perhaps the most typical use of routing functionality is sending a document to a sequence of recipients for review, and tracking the progress of the document through the cycle. You can see this scenario reflected in some of the discussions and samples presented in this section.

Other possible uses for routing are:

•	Sending a Web page to a group of editors for approval before posting it.

•	Passing expense reports to appropriate managers for review.

In the past, you might have chosen to build a sophisticated application that makes use of a database engine, a robust but perhaps costly solution. Or you could use the simple routing slips of Microsoft® Office. These routing slips are examples of client-side routing, which lacks a good way to ensure execution in a prescribed period of time or to guarantee that execution will complete. Because of this, server-side routing is probably a better choice.


Routing Architecture

Microsoft Exchange Routing uses a server-side, hub-and-spoke architecture. A Microsoft Exchange Public Folder (or a mailbox) acts as the hub, and the spokes are e-mail messages sent between each recipient and the hub folder. Logically, a route could be designed to move an item from user A to B to C, but each of these steps must go through the central hub in order for the state to be tracked centrally and for errors to be handled.

The following illustration shows the logical view of a simple route on the left. On the right, you see the actual movement of messages.

From an implementation perspective, Microsoft Exchange Routing can be seen as a state-driven scripting agent that uses four components:

•	A routing engine, which manages the state and state transitions of the route

•	A routing map, or state diagram, which describes the process logic to be used in the route

•	A set of objects to assist in manipulation of the map and other items

•	Scripts that describe the set of functions to be used in execution of the route

The routing engine has been implemented as a custom agent that runs under the control of the Microsoft Exchange Event Service. It is configured on a per-folder basis and responds to all the events generated by the Event Service on that folder.


Tracking an Item's Status

The routing engine that runs on the Microsoft Exchange Server computer automatically tracks the status of each item in the folder. It adds any comments made by recipients to the body of the original message, and it keeps track of who has approved or rejected the item so far. To view the status tracking information, you need to use Microsoft Outlook 97 (version 8.03 or later). Open the Microsoft Exchange folder where the routed items are stored and double-click any item to examine its status.

Tracking Posted Items

If the original item posted to a folder was a regular document or e-mail message, you see a Tracking tab when you open the item in Microsoft Outlook. This tab displays which recipients have responded, what time they responded, and whether they approved or rejected the item.

If the original item posted to the folder was a custom form, you do not automatically see a Tracking tab in Microsoft Outlook. The custom form would need to be modified to display status-tracking information.


Operation of the Routing Engine

As described previously, the routing engine is a state engine component designed to execute and track multiple process instances in a Microsoft Exchange folder. The engine is driven by events — specifically the OnMessageCreated and OnTimer events that occur in the Microsoft Exchange folder where the engine is installed. Whenever a new message arrives in the folder, or a timer (expiration) event is evaluated, the execution state of a process may get updated.

The primary focus of the engine is to simplify e-mail-based routing applications. The engine routes work items (such as forms or documents) to participants through e-mail. Participants send e-mail replies back to the engine in order to approve, reject, or comment on the item being routed. On the server, the engine tracks the responses and comments and provides support for exception handling in the event a time-out occurs, duplicate mail is received, and so forth. E-mail-based applications are only one class of workflow-enabled application, but they are an important one for Microsoft Exchange Server.

Note  Routes can be built using either public folders or private mailbox folders as routing hubs. However, routes built on private folders other than the Inbox will fail unless incoming mail is redirected to the folder that is acting as the routing hub. The redirection can be performed by an Inbox rule.


About Process Maps

The routing engine is programmed by creating a data structure called a process map, or map for short. This map can be thought of as a low-level description of the logic in a given process or route. This logic can be expressed as a series of activities; for example:

To request approval by a manager

1.	Send message to manager.

2.	Wait for either a response or for a specified time to pass — 24 hours, in this example.

3.	Evaluate whether a response was received or an expiration has occurred.

4.	If expiration, branch to time-out handler.

5.	Else, a message (a response) was received, so

6.	Open the message and collect the approval status.

7.	Evaluate whether the request was approved.

8.	If so, branch to approval handling.

9.	Else, branch to rejection handling.

You can encode logic at this level more or less directly into the routing map, as shown in the following table. This table, in which a manager's approval of an item is requested, is a simplified (pseudocode) view of a map for the preceding steps:

Activity ID	Action	Argument
10	Send	Manager's e-mail address
20	Wait	24 hours
30	ORSplit	IsTimeout
40	Goto	Time-out handler
50	Receive
60	ORSplit	IsApprove
70	Goto	Approved handler
80	Goto	Rejected handler
Maps are created and manipulated using the COM interfaces known as the Microsoft Exchange routing objects. Each row of a map consists of an Activity ID, an Action, and one or more parameters (arguments) for each action.


Enabling a Folder for Routing

The routing engine is implemented as a custom event handler running on the Microsoft Exchange Server 5.5 Event Service. In order to link the engine to the events firing in a given folder, an instance of this event handler (an Agent) must be created in the folder. This is also known as creating a binding between an event handler and a folder. This action creates a hidden binding message in the folder that describes the event handler, the events to act on, and any handler-specific properties. In the case of the routing engine, the handler-specific properties include the default map for the folder, and the set of VBScript actions (see Script Actions) to be used by maps in this folder.

Also see Sample Code: Enabling a Folder for Routing.


Creating a Process Instance

A new item arriving in the folder is the primary event that creates a new process or advances the state of an executing process. When the engine's OnMessageCreated event fires, the engine tries to correlate the new message to one of the existing process instances being executed. If the item is successfully correlated to a process instance, the state of that process is updated and the engine executes the next step in that process's map.

If the new item does not correlate to any existing process instance, a new process instance is created. To accomplish this, the engine performs several steps to transform the new item into a process instance:

1.	A new item arrives in a monitored folder.

2.	The routing engine inspects the item for an existing Map property. If it has no map, the default map installed in the folder is attached to the item as a new property. If the item has its own map, the default map is not attached, and an ad-hoc process definition (see the following section About Ad-hoc Processes) is submitted for the new WorkItem.

3.	The routing engine gives the item a number of new properties that make it a full-fledged process instance, including current status, a unique routing ID number, and so on. The WorkItem has now been transformed into a Process Instance Message (PIM).

The following diagram summarizes how the routing engine creates a new Process Instance Message (PIM):

About Ad-hoc Processes

A newly arrived item in a monitored folder can contain its own process map. A Microsoft Outlook custom form, for example, could use routing objects from within its script to create a map on a new item. When posted to the folder, the map on the new WorkItem is used instead of the default map for the folder. In this case, an "ad-hoc" process is said to have been defined for the item.

Executing the Process Map

When a new Process Instance Message is created, the engine begins executing the first activity in the PIM's map. If the activity calls for custom (VBScript) actions, the functions are found in the script that has been installed in the folder. Normally, this script consists of the default VBScript actions (see Script Actions) provided with Microsoft Exchange routing objects, but it could also be a customized version of these commands or even a totally new set of custom commands.

Execution of the map continues sequentially until it terminates. The execution sequence is controlled by the use of flow-control-oriented Intrinsic Actions.


About the Microsoft Exchange Routing Wizard

The Microsoft Exchange Routing Wizard is a sample application written in Microsoft Visual Basic 5.0. It allows authorized folder owners to define, for a folder being monitored, simple sequential or parallel routes. After a route is installed in a folder, any item posted or dropped into that folder is automatically routed to the specified recipients, and Microsoft Exchange Server automatically tracks the status of the item.

To run the Microsoft Exchange Routing Wizard sample application, a user must be the owner of the monitored application folder, and have permissions to install and run scripts on the Microsoft Exchange Server; see Granting Permissions.

Note  For installation instructions, see Installing the Routing Wizard Sample Application.


Installing the Routing Wizard Sample Application

The Routing Wizard sample application is on the distribution CD of Microsoft Exchange Server version 5.5, SP1. It can be installed on either the Microsoft Exchange Server computer or any client computer — a Windows NT or Windows 95 workstation.

Microsoft Outlook 98 must be installed on the computer where you run the Routing Wizard.

To install the Routing Wizard sample application

1.	Open the appropriate folder on the Microsoft Exchange Server version 5.5, SP1 distribution CD:

If you're running Windows 95:

\Eng\Server\Support\Collab\Sampler\Routing\win95

If you're running Windows NT:

\Eng\Server\Support\Collab\Sampler\Routing\Winnt\i386

2.	Double-click the file RWSetup.exe.

This installs the Routing Wizard sample application on the computer containing the distribution CD.


Using the Routing Wizard Sample Application

The Routing Wizard sample application illustrates the type of routing tools that can be built easily with Microsoft Exchange Routing. With the Routing Wizard you can define and install simple sequential or parallel routing and approval logic into Microsoft Exchange Server folders.

Once installed, these folders will automatically route any items they receive according to the route you defined. Microsoft Exchange Server then automatically tracks the progress of the item being routed, including handling of items that have expired.

The Routing Wizard works by installing a process map into a Microsoft Exchange Server folder. This process map defines the steps in the route, how time-outs should be handled, and so on. As the Routing Wizard asks a series of questions your answers are used to build and define the process map.

After you enable your chosen folder for routing, the folder uses e-mail to forward anything posted to each defined recipient in turn. Each recipient can review the item being routed and vote to approve or reject the item. If the recipients are using Microsoft Outlook clients, they can use Outlook Voting Buttons to approve or reject the item. With most other mail clients, recipients can click URLs to send their approval or rejection.

Required Permissions

The Routing Wizard helps define and install routing related script code into the chosen Microsoft Exchange Server folder. In order to install a route using the wizard,

1. 	You must be the owner of the chosen folder.

2. 	You must have been granted permissions to install and run scripts on this Microsoft Exchange Server computer.

Note  If you are the owner of the folder but do not have the install permission, you will still be allowed to define a route, and the wizard will finish normally.  However, the route will not be "activated" until an administrator or someone else with script permission runs the wizard again and saves the route you have defined.  When the route is saved, the routing engine is registered and the routing scripts are installed for the folder.

Warning  The install privilege should be given only to trusted users because it allows people to install new script code on your production e-mail servers. For more information, see Granting Permissions, and also see the Microsoft Exchange Server 5.5 Release Notes for further information on the security implications of scripting privileges.


About the Role Administrator Sample Application

Role Administrator is an ADSI sample application used for creating roles and associating those roles with mailboxes.

A role is a special type of distribution list in which the owner of the distribution list, known as the role performer, becomes the recipient when selected through the Routing Wizard sample application. Only an administrator of the Microsoft® Exchange Server can create these roles.

Note  Roles of this type reside in the Microsoft Exchange Server directory and are not to be confused with the roles used to control permissions on folders in a Microsoft Exchange Server information store.

After a role has been created, a person using the Routing Wizard to create a route can use this new role as a recipient in the route. Currently, the Routing Wizard supports only the role of manager. Manager is defined as the person listed as the recipient's manager in the Microsoft Exchange global address list.


About Roles

A role is an abstract relationship between people in an organization. For example, the role of Expense Approver is usually performed by a person's manager. In fact, a person's manager might perform many roles, for example the roles of Performance Reviewer, Vacation Approver, Task Assigner, and so forth. This abundance of de facto roles for managers is the reason the Routing Wizard by default recognizes the Manager role.

Roles are one-directional, so role relationships can be expressed by sentences like "Jim performs the role of Manager for Sharon." For this reason Jim is refered to as the role performer of the Manager role for Sharon. It is possible that several people in the organization might have the same role performer for a given role. For example, everybody who reports to Jim will have the same role performer for the Expense Approver role — namely, Jim.

Roles are valuable because they make it possible to build general workflow instructions that refer to the relationships between people and not to their particular identities. For example, the first step in an expense approval workflow does not have to be saved as "Submit Sharon's expense report to Jim," but can be saved as "Submit X's expense report to the person performing the role of Expense Approver for X." In this way powerful line-of-business workflows can be defined, encapsulating generalized business logic.

Roles are implemented as nested distribution lists. For example, the Expense Approver role is represented by a distribution list, each member of which is also a distribution list. Each of these nested distribution lists represents a performer of the Expense Approver role, encoded as the owner of the distribution list. The members of the nested distibution lists are the people for whom the owner of the distribution list performs the Expense Approver role.


Installing the Role Administrator Sample Application

Before you install the Role Administrator sample application, be sure you have the following software installed on your computer:

•	Microsoft® Windows NT® Server, running on an Intel computer.

•	Microsoft® Internet Information Server (IIS) version 3 or version 4.

•	Active Server Pages  You can choose to install Active Server Pages when you install Windows NT Server version 4, Service Pack 3.

•	ADSI 2.0  For information on obtaining ADSI as a free download, see http://backoffice.microsoft.com/downtrial/moreinfo/adsi2.asp. ADSI will also be made available in the CD-ROM set of the Microsoft Developer Network (MSDN™).

Installation of the Role Administrator sample application has two parts, as described in the following procedures. First, install the Role Administrator sample itself, and then set up a virtual directory, which requires different steps depending on your version of IIS.

Note  The Role Administrator sample application, which is Web-based, is designed to be used with Microsoft® Internet Explorer. Other browsers may exhibit inconsistent behavior.

To install the Role Administrator sample application

1.	Open the following folder on the Microsoft Exchange Server version 5.5, SP1 distribution CD:

\Eng\Server\Support\Collab\Sampler\Routing\Winnt\i386

2.	Double-click the file RoleAdmin.exe. The Role Administrator sample application, which consists of a number of .asp files, is installed by default in the \Program Files\Rtadmin folder; if you prefer, you can choose a different destination folder.

3.	Set up a virtual directory for the Role Administrator sample application. If you are running IIS version 3.0, see To set up a virtual directory with IIS 3.0. If you are running IIS version 4.0, see To set up a virtual directory with IIS 4.0.

To set up a virtual directory with IIS 3.0

Setup does not automatically create the virtual directory for you, but requests that you create one with Read and Execute permissions.

1.	Start the Internet Service Manager. To do this, click the Windows NT Start button and then point to Programs. Point to Microsoft Internet Server and click Internet Service Manager.

2.	Double-click the computer listed as running the WWW service. The Service Properties dialog box for that computer is displayed.

3.	Click the tab to display the Directories page.

4.	Click Add. The Directory Properties page is displayed.

5.	Click Browse. In the Select Directory dialog box, find and click \Program Files\Rtadmin, the directory in which Role Administrator was installed. Click OK. The Directory Properties page is displayed once more.

6.	You can choose to assign a new name, such as "RtAdmin," to the virtual directory by typing the name in the Alias text box.

7.	In the Access group box, select Read and Execute. Click OK.

8.	Click the tab to display the Service page.

9.	Clear Windows NT Challenge/Response and select Basic (Clear Text). Click OK. If you see a warning dialog box, click Yes if you want to close the warning and continue. Click OK to close the Service Properties dialog box.

10.	Click the Windows NT Start button and then point to Programs. Point to Administrative Tools and click User Manager for Domains.

11.	Click Select Domain on the User menu. The Select Domain dialog box is displayed.

12.	Type your domain name in the Domain text box using the format \\<domain name>, and click OK.

13.	On the Policies menu, click User Rights.

14.	On the Right: pull-down menu, click Log on Locally.

15.	In the Add Users and Groups dialog box, click Add and then click Everyone. Click OK.

16.	Click OK to close the User Rights Policy dialog box.

17.	Close the User Manager.

The Role Administrator is set up. To run it, see Running the Role Administrator Sample Application.

To set up a virtual directory with IIS 4.0

1.	After the Role Administrator sample application is installed, the Create Virtual Root dialog box is displayed. In the Name of This IIS 4.0 Server text box, type the name of your IIS computer. Click OK.

2.	In the Visual Basic 5.0 Setup Toolkit dialog box, enter the name of the virtual directory. The virtual directory is named "Rtadmin" by default but you can assign a different name if you prefer. Click OK. The new virtual directory points to the file-system directory \Program\Rtadmin.

3.	Click the Windows NT Start button and then point to Programs. Point to Administrative Tools and click User Manager for Domains.

4.	On the User menu, click Select Domain. The Select Domain dialog box is displayed.

5.	Type your domain name in the Domain text box using the format \\<domain name>, and click OK.

6.	On the Policies menu, click User Rights.

7.	On the Right: pull-down menu, click Log on Locally.

8.	In the Add Users and Groups dialog box, click Add and then click Everyone. Click OK.

9.	Click OK to close the User Rights Policy dialog box.

10.	Close the User Manager.

The Role Administrator is set up. To run it, see Running the Role Administrator Sample Application.


Running the Role Administrator Sample Application

Before you run Role Administrator, it is best to know the terminology used when working with roles:

A role performer DL (distribution list) is a group of people capable of performing a given function, such as approving an expense request. Within that group, an owner of the role performer DL is known as a role performer. Other people within the group are known as members. A DL can have only one owner. For more information, see About Roles.

To run the Role Administrator

1.	Start Microsoft® Internet Explorer.

2.	Enter the URL of the server on which IIS is running and the name of the virtual directory you created in Installing the Role Administrator Sample Application. The Routing Role Web Administrator logon screen is displayed. Use the format http://<server name>/<virtual directory>.

3.	Log on. To do this, enter the names of your Microsoft Exchange Server organization, site, and server. Click Continue.

4.	If the Enter Network Password dialog box is displayed, enter your user name in the format <domain name>\<user name>. Enter your password in the appropriate text box. The Routing Role Tree screen is displayed in the left pane.

5.	Click the Create New Role button in the left pane. The Create New Role screen is displayed in the right pane.

6.	Type the name of a role in the Role Name text box. Click Create Role. The Role Editor screen is displayed in the right pane.

7.	Select New Role Performer to create an owner of the role. The New Role Performer screen is displayed.

8.	In the Role Performer text box, enter the name of a recipient in the Microsoft Exchange Server directory. Click Find Role Performer. The Find Role Performer screen is displayed.

9.	Select the name of a role performer from the drop-down list box. Click Select Role Performer.

10.	Existing roles are displayed in the left pane. To edit a role, click it. The Role Performer Editor screen is displayed in the right pane. You can use this screen to add members to the role (a distribution list). You can also remove members, or modify or delete role performers.

11.	When you are finished, close Microsoft Internet Explorer.


About Routing Map Actions

A routing map contains two kinds of actions:

•	Basic flow-control activities are built directly into the routing engine. See Intrinsic Actions.

•	Script Actions  This default set of actions is used for functional activities or condition evaluation, the most common document routing and approval scenarios. They are implemented in the VBScript language, so you can readily customize them.


Intrinsic Actions

Some of the actions used in a map are intrinsic, or built in to the routing engine. These actions are used primarily for process and flow-control; they control the execution of the map.

Note  When creating a Row using these actions, the Flags property must be set to 0.

The intrinsic actions include:

Action name	Arguments	Description
AndSplit	Activities as Array of Long	AndSplit is used for parallel branching. It creates one or more new subprocesses that execute independently; the logic branches in parallel. The arguments are an array of Activity IDs (line numbers). The routing engine creates a new process instance for each entry in the array. The new process contains the same map but begins execution at the specified line number. Each subprocess executes separately until it encounters a Terminate statement. The main process continues executing only when all its subprocesses have terminated.  It is the responsibility of the developer to ensure that each subprocess has a valid Terminate action. It's also the developer's responsibility to extract any necessary data from the subprocess's process instance message before the process terminates. Typically you would use the Consolidate script action to consolidate properties from the subprocess PIM onto the parent PIM as the last step before termination.
Goto	ActivityID as Long	Jump to specified activity in the map (line number) and begin executing there. ActivityID is the line number that identifies an activity (a row) in the process map.
New	ActivityID as Long	Instantiates a new route process instance
OrSplit	EvalFunction as String	An "IF" statement. Requires the name of a Boolean VBScript function that evaluates to either TRUE or FALSE. If TRUE, the next row of the map is executed. If FALSE, the next row of the map is skipped, and the following row executed.
Terminate	(none)	Ends the currently-executing process instance.
Wait	Time as Long	Wait the specified number of minutes; then execute the next row.


Script Actions

The routing engine can be extended to perform application-specific actions that are implemented in script. Only the VBScript language is currently supported. The action's name is the name of a VBScript function; the action's parameters are the parameters of that VBScript function.

A default set of VBScript actions for common routing and approval applications is included in the file ROUTING.VBS, which is currently available on the web at http://www.microsoft.com/exchange/appfarm. The Routing Wizard sample application uses these script activities extensively.

Script actions are of two types, evaluation and functional:

Evaluation Actions

Action	Description
IsTimeout	Branches if the current item has expired.
IsReceipt	Branches if the current item is a receipt, of one of the following three kinds: delivery receipt, read notification, not-read notification.
IsApprovalMsg	Branches if the reply is Approve or Reject.
IsApprovedTable	Branches on the overall approve/reject status for a set of parallel recipients (evaluates the complete list of votes).
IsInvalidRecip	Verifies that a response message received has come from the person in the routing sequence who received the item and from whom a response is expected.
IsOOF	Branches if the triggering message is an out-of-office message.
IsPost	Branches if the triggering message is a Post message — a message with message class IPM.Post.
Functional Actions

Action	Description
Send	Sends a "routing-slip" e-mail message to the specified participant. The routing-slip can contain either a Microsoft Outlook Web Access link to the WorkItem, or the WorkItem itself as an attachment. The participant address can be an explicit address or a role.
Receive	Processes any reply messages that successfully correlate to an existing PIM. Handles voting-button and status-tracking information.
Consolidate	Takes the message body and attachments of any reply messages, and merges them into the original PIM.
FinalizeReport	Creates/sends a summary report of the PIM status.
PreProcessing	Performs any necessary preprocessing on the PIM, such as changing its message class to IPM.Note in order to use Outlook's tracking page.
AutoSet	Provides default approval or rejection functionality for participants.


Routing Objects

Developers can create and manage maps, control process instances, and more by using Microsoft Exchange routing objects. These are dual-interface COM objects that allow simple programmability from C++, Visual Basic, or scripting languages such as VBScript.

Microsoft Exchange routing objects are designed to be used in conjunction with Microsoft Collaboration Data Objects (CDO), version 1.2.1. Many of the data types used in the following topics (for example, Message and Folder) are defined in Collaboration Data Objects.

Object Hierarchy for Routing

RouteDetails

          ProcInstance

                    Map

                              Row

                    Log

                    Participant

                    VoteTable

          WorkItem

WorkItem

VoteTable

Map

Log


WorkItem

The WorkItem object represents the data to be routed or approved. It is typically posted or mailed to the application folder in order to start a process. This object is essentially a CDO Message object, wrapped with additional interfaces for correlation and consolidation. In general, most user-level applications do not need to explicitly call the methods of WorkItem. The routing engine automatically handles item correlation in most cases, and the default VBScript action Consolidate can be used to consolidate response properties back onto the original message for tracking purposes.

Property	Type	Access
Item	Message	Read/write
Methods	Parameters
ItemCorrelate	[in] SetPropertyID as Long [in] Folder as Folder [out] Target as Message
ItemConsolidate	[in] PropertyList as Array of Long [in] SourceMessage as Message [in] Append as Boolean
EmbedMsg	[in] Item as Message


Map

The Map object represents the process map used to execute and track a particular process instance. There must be a default map in every routing-enabled folder.

The default map for a folder is stored on a hidden (folder-associated) message in the folder. This message is part of the event binding that is used to register the routing engine as an event handler in that folder. The EntryID of this message is obtained from the Binding.EntryID property. The OpenMap and SaveMap methods take this message as an argument.

A Map is a top-level object and can be created independently. This means that you can place a map on a message, and it will override the default map of the monitored folder. Also see About Process Maps and Enabling a Folder for Routing for more information about maps.

Note  Calling the SaveMap function does not automatically cause the map to be saved. You must modify at least one other CDO property in order for a subsequent Message.Update statement to successfully save the map.

Property	Type	Access
ActivityCount	Long	Read-only
Message	CDOMessage	Read/write
Methods	Parameters
CopyTo	[in] Target as Message
DeleteActivity	[in] ActivityID as Long
DeleteMap	(none)
GetActivity	[in] ActivityID as Long [out] Row as Row   [out] RowNo as Variant
GetRow	[in] RowNo as Long [out] Row as Row
InsertActivity	[in] RowAfter as Long [in] Source as Row
OpenMap	[in] eMode as Long	(0 = read-only, other = read/write)
SaveMap	(none)


Row

The Row object represents a single row (a single activity) in the process map. A Row object is a top-level object and can be created independently. After creating a new row, you provide values for the Action, ActivityID, and Flags properties, where ActivityID is a unique line number identifying the row, Action is the name of the action to be performed, and Flags denotes the type of action (intrinsic or script).

The remaining columns in a Row are an array of arguments, set using the SetArgs method. The number of arguments is dependent on the particular Action function used. Argc is the number of arguments, and Argv is a string array containing the argument values.

Property	Type	Access
Action	String	Read/write
ActivityID	Long	Read/write
Flags	Long	Read/write (0 = Intrinsic Action 2 = Script Action)
Methods	Parameters
CopyTo	[in] Target as Row
GetArgs	[out] Argc as Long [out] Argv as Array of String
SetArgs	[in] Argc as Long [in] Argv as Array of String


ProcInstance

The ProcInstance object represents an instance of a process being executed. Sometimes called the PIM (Process Instance Message), this object consists of the original MAPI message consisting of the WorkItem plus additional properties for the state and map information.

The ProcInstance object is a top-level object that can be created independently, or obtained through the RouteDetails object. After creating the object, in order to use it you must associate it with the specific message that it is stored in by using the Open method.

Property	Type	Access
CurrentRow	Long	Read/write
Log	Log	Read/write
Map	Map	Read/write
Message	CDOMessage	Read/write
ParentProcID	EntryID	Read-only
Participant	Participant	Read-only
RUI	Long	Read/write
Session	CDOSession	Read/write
Status	String	Read/write
SubProcCount	Long	Read-only
Terminated	Long	Read-only
Timeout	Boolean	Read/write
VoteTable	VoteTable	Read-only
Wait	Long	Read/write
Methods	Parameters
EngineOpen	[in] eMode as Long
Open	(none)
Save	(none)


Log

The Log object provides a method of logging the execution of individual activities in the map. ISVs or other developers may wish to expose the log in their tools for debugging or other purposes.

Log is not a top-level object that can be separately created. It must be obtained via the Log property of a ProcInstance object.

Property	Type	Access
Message	CDOMessage	Read/write
Methods	Parameters
AddLogEntry	[in] Application as String [in] NameID as String [in] DateTime as Long [in] Descrip as String
GetLogEntry	[out] Application as String [out] NameID as String [out] DateTime as Long [out] Descrip as String [out] LogIndex as Integer
OpenLog	(none)
SaveLog	(none)


Participant

The Participant object provides an abstract way to refer to and manipulate the e-mail addresses to be used for routing applications. The ResolveRole method works in conjunction with specially constructed distribution lists in the Microsoft Exchange global address list to provide dynamically modifiable "roles" and "relationships."

Property	Type	Access
(none)
Methods	Parameters
Session	[in] Session as Session
RoleName	[in] Role as string
MemberName	[in] Member as string
ResolveRole	[out] bstrAddress as string


RecipientEntry

The RecipientEntry object is used to access and manipulate the summarized status information on a process instance. This information is stored as properties on the Recipients table of the process instance message.

Property	Type	Access
Date	String	Read/write
Recipient	String	Read/write
Status	String	Read/write
Methods	Parameters
(none)


VoteTable

The VoteTable object provides a way for server applications to programmatically create Microsoft Outlook-compatible "Voting Button" properties on a message.

Property	Type	Access
Count	Long	Read-only
Item	Index as Long [out] RecipientEntry	Read-only
PIMessage	Message	Read/write
Methods	Parameters
AddButtons	[in] Msg as Message [in] VoteOptions as String
ConsolidateResponse	[in] SourceMsg as Message [in] autoadd as Boolean
Save	(none)


RouteDetails

The RouteDetails object contains the details of the route; the route engine supplies it to the routing script in the same way it supplies EventDetails to the routing script.

The RouteDetails object is a top-level object that script writers must use to obtain objects on the next level. Specifically, it provides the process instance (ProcInstance object) and can also be used to create WorkItems.

Property	Type	Access
ProcInstance	ProcInstance	Read-only
Methods	Parameters
CreateWorkItem	[out] WorkItem as WorkItem


Microsoft Routing Glossary

Activity

An activity defines what happens in the routing map at a particular state. Examples are "SendMessage", "Goto X", "Wait", and so on.

ADSI

Active Directory Services Interface (ADSI) is a set of COM interfaces that can be used to create directory-enabled applications.

CDO

Microsoft® Collaboration Data Objects (CDO) is a technology for building messaging or collaboration applications.

Process instance

The data for an individual routing process is stored in a process instance. This data includes the process map, a tracking table, a log, and the original posted message. All this data — in other words, the process instance itself — is stored on a hidden message in the folder being monitored. A process instance models a particular route and stores all the information for that route. For example, dropping a spreadsheet into a folder will cause a process instance to be created and the spreadsheet to be embedded in it.

Process instance message (PIM)

A process instance message stores process instance information and, usually an attachment that holds the data of the message.

Process map

A process map is a definition for either a sequential or a parallel route among Microsoft Exchange Server folders.

Routing map

A routing map lists all the possible states in a route. It is traversed from top to bottom, much like a program, and branches when indicated by a particular state.

State engine

A state engine governs the ways items can move from one state to another. In Microsoft Routing, the routing engine uses the states of items within a process map, combined with the occurrence of events, to advance the item's state through the process map.

Work item

Any new item in a folder is modeled as a work item until the process instance it relates to is found, or — if none is found — it is used as the basis from which to create a new process instance.