Are you a world traveler? ZoneTick is a cool utility that'll help you stay in touch over multiple time zones!
 
Creating Folders Scripts  
Nik Okuntseff  MS Exchange Server Programming 

Creating Folder Scripts

When everything is properly setup you may try to create and run a simple script. This is how it can be accomplished:
  • Create a new folder or, if you are going to experiment with an existing folder, make sure you have an Owner client permission on this folder. Display properties dialog for the folder (right click and choose Properties). Select the Agents tab.
  • Press the New button to introduce a new agent. An agent is a Microsoft provided component that will run your script when specified events occur. Choose appropriate agent name (for example, MyAgent) and check "A new item is posted in this folder" in the list of events.
  • Press "Edit Script..." button. Outlook would start notepad to allow you to edit a file with the .asp extension. This active server pages file may look like the following:
<SCRIPT RunAt=Server Language=VBScript>

'------------------------------------------------------------------------------
'FILE DESCRIPTION: Exchange Server Event Script
'------------------------------------------------------------------------------

Option Explicit

'------------------------------------------------------------------------------
' Global Variables
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
' Event Handlers
'------------------------------------------------------------------------------

' DESCRIPTION: This event is fired when a new message is added to the folder
Public Sub Folder_OnMessageCreated
End Sub

' DESCRIPTION: This event is fired when a message in the folder is changed
Public Sub Message_OnChange
End Sub

' DESCRIPTION: This event is fired when a message is deleted from the folder
Public Sub Folder_OnMessageDeleted
End Sub

' DESCRIPTION: This event is fired when the timer on the folder expires
Public Sub Folder_OnTimer
End Sub

</SCRIPT>

As you can see, the script does nothing. For subroutines are provided, one for each type of event (message creation, change or deletion, and a timer event), but they are empty. Save the script without introducing any changes.
 

Examining the System with Empty Script

To see whether we are on track here after introducing a script that does nothing let us examine the folder's associated contents table to see a pair of hidden messages. They define this script, have the subject equal to the name of the agent, and have IPC.Microsoft.ICS.EventBinding and IPC.Microsoft.EventBinding message classes. Also, if you stop and restart the Event Service, you should see a message (Event ID 16388) in the Application Event Log that this folder is now monitored. Also, try to post a message to the folder and observe that the system behaves normally doing nothing. An indication of normal operation would be absence of any error messages in the Application Event Log 1 minute or more after postings. As I have described earlier, 1 minute is the default delay between communicating content changes from Exchange information store to Event service.
 

Examining the System Behavior with Bogus Script

The next logical step would be modifying the script to do something. Let's try to introduce a bogus command and see what happens. Modify the Folder_OnMessageCreated subroutine by introducing a command that VBScript will be unable to execute, like here:

Public Sub Folder_OnMessageCreated
    MyBogusCommand
End Sub

Save the script and post a message to the folder. Give the system enough time to process the event (2 minutes or more) and then examine the Application Event Log. You should see there a MSExchangeES Event ID 12 describing the error occurred:

"A fatal error (0x86664004) occurred in an IExchangeEventSink while processing message [Subject = "My Subject"]. 09/06/98 15:27:53 Run time error at line 19. Source: Microsoft VBScript runtime error Error: 800a01f4. Description: Variable is undefined: "MyBogusCommand"

followed by Event ID 25:

"Script failed with a run time or syntax error on the last event. Since the script was not modified since the last failure, the script will not be run again until the error is fixed. Please refer to agent log for more information about the failure."
 

Testing a Good Script

Let's replace an invalid command with something that makes sense. Perhaps a good example would be trying to output some debugging information. This may be accomplished by utilizing the Script.Response object as in this example:

Public Sub Folder_OnMessageCreated
    Script.Response = "Inside Folder_OnMessageCreated"
End Sub

If you test this modified script, you normally should not see any errors. Also, debug information that the script writes will be available if you press the "Logs..." button on Agent Edit dialog. Notice that errors are also logged there.

Alternatively, you could try the following more interesting example, that automatically sends a reply to message originator:

Public Sub Folder_OnMessageCreated
    Dim SourceMsg
    Dim ReplyMsg
    Dim Recipient

    'Create a new message
    Set ReplyMsg = EventDetails.Session.Outbox.Messages.Add

    'Set subject and body
    ReplyMsg.Subject = "Hello, world!"
    ReplyMsg.Text = "Hello, world!"
 
    'Address the message
    Set Recipient = ReplyMsg.Recipients.Add
    Set SourceMsg = EventDetails.Session.GetMessage(EventDetails.MessageID, Null)
    Recipient.Name = SourceMsg.Sender
    Recipient.Type = 1 'This means CdoTo
    Recipient.Resolve

    'Send the message
    ReplyMsg.Send
End Sub

Now if somebody posts a message to this public folder, a reply "Hello, world!" message will be sent automatically back. For this illustration code as pretty much for every sample code in this book I have removed all error handlers. For example, the Resolve method may fail if mailboxes with similar names exist (such as Test and Test1), and you are posting a message using one of these mailboxes. Apparently, a proper error handling of all possible errors is needed for production code. If your script fails it will be immediately disabled by Exchange server.
 

Limitations of Folder Scripting
 
VBScript is a subset of VBA, which is a subset of VB. It has only one data type, which is a Variant. Through it you can reference almost anything at expense of performance. You can do a lot of things with VBScript. For example, you can use collaboration data objects within scripts, as the above example demonstrates. However, some things are problematic (writing to files, registry access, etc.), or impossible (multithreading). You may have noticed that I have used the Script.Response object for debug output. This is by design. This scripting environment was designed to simplify usage of complex things, such as MAPI, from a variety of environments. For example, scripts are very useful in active server pages programming. A programmer or web developer with limited knowledge of details may become productive very fast by learning object models and just using their methods. It all comes with a price, of course. It is easy to start but difficult to follow. Advanced things are difficult to achieve, as perhaps many things that slightly differ from VBScript design goals. At some point you may still come across a need to write fast components using different development environments. However, you may design those components in a way that they are accessible via a scripting language.

The following objects are created by Exchange server and passed to the processing script:

  • EventDetails.Session - a CDO session (a top-level object in CDO hierarchy). Access to other objects such as folders and messages may be obtained through it. It is important to understand that scripts run in the security context of their authors (users who install scripts into Exchange server). The script may process messages from anyone, but its security context  and associated collection of access rights is defined by that of given to the script author. For example, in the "Hello, World!" example above the sender of the "Hello, World!" auto reply will be a user who had originally created the script.
  • EventDetails.FolderID - entry identifier of the folder where an event had occurred.
  • EventDetails.MessageID - if the script was fired by a message (not a timer event), this would represent its entry identifier.
Also, as I have shown above, the Script.Response object may be used to log information. For example, you can use it for debugging purposes to trace progress of script execution.
 
[ Contents | Home ]

Send comments and suggestions to niko@wrconsulting.com
Copyright © 1997-1998 by Nik Okuntseff