If you install Windows Scripting Host (WSH) with Microsoft Outlook 97/98 or Internet Explorer (IE) 4.0's Outlook Express, you can use the Messaging API (MAPI) with Outlook's or Outlook Express' Application object to automate messaging. (Earlier Outlook Express versions don't support MAPI.) You can use WSH with MAPI to customize your scripts in many different ways. For example, you can make sure a script has run successfully by having the script send you a message, or you can add WSH code that automatically sends messages at predetermined points to log who is running a script.

You can write a logon script that displays how many new messages a user has, which of those messages are urgent, and the urgent messages' sender and subject line. If you want to keep tabs on a particular user for security reasons, you can add code to that user's personal logon script to notify you via email when the user logs on. You can write scripts that manipulate and scan folders, post Public Folder messages, schedule tasks, and search the Contacts list.

Access to the Application object lets you script MAPI calls from the command line rather than from within an application. Because you aren't developing forms and scripts from within the application, you're not limited to using Visual Basic Script (VBScript). You can use any component object model (COM)-savvy scripting language, including Perl and JavaScript. As a result, although I'm using VBScript in the example listings, you can easily adapt them to other scripting languages. (If you're unfamiliar with WSH and its scripting engine, VBScript, see Michael Otey's "An Introduction to WSH," page 7.)

Before you can start writing a script, you must install Outlook on the machine executing the script. (Your scripts will be of little use on another email client.) You also need a basic understanding of Outlook's object model and several Collaboration Data Objects (CDO).

The Objects
Figure 1 shows Outlook's object model. Although Figure 1 shows the basic hierarchy of objects, it doesn't show the many different objects available for use. Because Outlook has too many objects to cover in this article, I will discuss some of the objects I have found most useful for automated messaging.

Application object. This object represents the entire Outlook application. You use this object to create items (e.g., email messages) and access Outlook functions (e.g., Office Assistant).

NameSpace object. This object represents the message store, which you access using MAPI. (Outlook supports only the MAPI namespace.) The NameSpace object lets scripts log on to and log off from Outlook. It also provides objects that let you reference items, such as the current user and a list of folders and their contents.

MAPIFolder object and Folders collection object. The MAPIFolder object represents one folder (e.g., InBox) in Outlook. This folder can contain Outlook items (e.g., MailItem objects) or other MAPIFolder objects if you have a nested folder tree. The Folders collection object represents all the folders in Outlook.

MailItem object and Items collection object. The MailItem object represents one message in a mail folder, such as the InBox folder. The Items collection object contains those Outlook items in a folder. These items include the MailItem object (the default item) and 10 other types of Outlook items.

Recipient object and Recipients collection object. The Recipient object represents an Outlook user or resource. The Recipients collection object contains all the Recipient objects.

For more information on these and other objects, go to the Microsoft Developer Network (MSDN) Web pages at
theUR=/msdn/library/officedev/office/output/f1/d5/s5b056.htm and

When you use VBScript to automate Outlook, you can use CDO objects. A CDO Session object, which is a top-level object like the Application object, is particularly handy. Through the Session object, you can access the following objects.

AddressList object and AddressLists collection object. The AddressList object represents an address book available to a user. The AddressLists collection object holds one or more AddressList objects.

AddressEntry object and AddressEntries collection object. The AddressEntry object represents an individual entry or a distribution list containing other AddressEntry objects in an address book. The AddressEntries collection object holds one or more AddressEntry objects. More important, this collection object lets you access the contents of each address book.

Now that you're familiar with what these CDO and Outlook objects do, I'll demonstrate simple uses for them. But first I'll show you how to establish a connection to, or authenticate to, the Outlook application.

Authenticating to Outlook
You must authenticate to Outlook to gain the ability to work with Outlook objects in a script. As Listing 1 shows, you authenticate to Outlook by first creating an instance of the Application object. Then you use that object's GetNameSpace method with the MAPI parameter to create a reference to the MAPI namespace.

You don't need to authenticate to an Outlook session, because session calls automatically use the default Outlook profile of the current user. If you want to authenticate to another user's profile, you can use the NameSpace object's Logon and Logoff methods. (You can find the code and commentary for these methods in the sidebar "How to Authenticate to Another User's Profile.")

After authentication, you can use Outlook's objects for many purposes. As the following examples show, these purposes include creating and sending an email message, creating other messaging items, manipulating folders, and creating and delegating a task. To save space, I haven't included Listing 1's authentication code in the following examples, but you need to include it at the beginning of your scripts.

Creating and Sending an Email Message
Writing a script to send an email message is fairly simple. You just use the MailItem object. However, because this object has 61 properties and 13 methods, selecting which properties and methods to use can be intimidating. I created Listing 2 to show you the methods and properties that script writers often use.

As Listing 2 shows, you first need to create a MailItem object (objMail) by using the Application object's CreateItem method with the numeric value of 0. The numeric value represents a constant; in this case, 0 represents the MailItem constant. When automating Outlook with VBScript, you must use numeric values rather than constants because VBScript doesn't support Outlook's built-in constants. Throughout this article, I'll provide the values for the objects I'm discussing. (For a more complete list of constants and their numerical values, go to

After you create objMail, you need to specify the message's recipients in the appropriate fields. You can put recipients in the To field (value of 1), carbon copy (Cc) field (value of 2), and blind carbon copy (Bcc) field (value of 3). You can also list the message's originator in the From field (value of 0).

The To field is the default field type. Callout A in Listing 2 shows how you can use the MailItem object's To property to specify recipients in this field. The recipients include one resolved name ( and two address book names (Paul Burke and Simon Williams) that Outlook resolves automatically when the script sends the email messages.

Although there are Bcc and Cc properties that you can use in the To field in callout A, you can add recipients another way with the Recipient object and the Recipients collection object. As Listing 2 shows, you create an object reference to a new Recipient object (objRecipient1) and use that new object to access the Recipient collection object. You then use the Recipient collection object's Add method to add the recipient, Ian Harcombe. Next, you use the Recipient object's Type property to specify the field you're adding this recipient to. In this case, you're adding Ian Harcombe to the Cc field. You repeat this process to add objRecipient2 (i.e., Markie Newell) to the Bcc field.

After designating the recipients, you need to set the message's priority level using the MailItem object's Importance property. You can choose from three values: 0 (low importance), 1 (normal importance, which is the default), and 2 (high importance). As Listing 2 shows, the script's message is of high importance.

Now you must use the MailItem object's Subject and Body properties to include the message's subject line and body. Because the subject line and body are text strings, you can use file-manipulation routines to import the text from a file if you choose.

You can also choose to include an attachment to the message using the Attachments collection object's Add method. You must specify the type of attachment. You can select from four types: a file (value of 1), a link to a file (value of 2), an Object Linking and Embedding (OLE) object (value of 3), and an embedded message (value of 4). If you attach a link to a local file, recipients on remote networks can't access the attachment. If you're using the Internet-only version of Outlook, you can send only embedded attachments. In Listing 2, the attachment is a file, so you need to specify the file's explicit path (i.e., Uniform Naming Convention—UNC). If you don't add attachment files using Outlook's GUI, you have to explicitly reference the files for the script to use them. The script ends by using the MailItem object's Send method to send the message to your Outbox, where the message waits for Outlook to send it to the recipients at the appropriate time.

Creating Other Messaging Items
The MailItem object is but one of 16 item objects in Outlook. Table 1 lists the item objects and the corresponding values for those item objects that you will likely use in your scripts. (For more in-depth descriptions of Outlook's items, go to

Each item object has a set of properties and methods you use to create and manipulate other objects. For example, Listing 3, page 3, contains a script that creates a ContactItem object (objContact) and adds it to a user's Contacts folder. This script contains only a few of the 130 properties you can set for a contact. Setting certain fields automatically sets other related fields. For example, in Listing 3, setting the first and last name fields automatically sets the full name field to "Keith Cooper" and the initials field to "K.C." Thus, you don't need to include those fields in your script.

Manipulating Folders
Having described how to create items, I'll now show you how to manipulate the folders that hold those items. Outlook's default folders and their values are:

  • Deleted Items (3)
  • Outbox (4)
  • Sent Mail (5)
  • InBox (6)
  • Calendar (9)
  • Contacts (10)
  • Journal (11)
  • Notes (12)
  • Tasks (13)

The process you use to manipulate folders is similar to the process you use to create items. As before, you first create a reference to an object. But instead of using the Application object's CreateItem method, you use the NameSpace object's GetDefaultFolder method with the default folder's value. For example, if you want to work with the InBox folder, you use the code

Set objInBox = mapiNameSpace _.GetDefaultFolder(6)

To manipulate folders, you need to know how to use VBScript statements, such as For Each...Next and If...Then. (If you're unfamiliar with VBScript statements, go to Microsoft's VBScript Language Reference Web site at

Listing 4 shows an example script that uses the For Each...Next statement to iterate and display the contents of two folder lists. The first part of the script uses the For Each...Next statement to iterate through the folders underneath the top level of the folder hierarchy (i.e., MAPIFolder) and displays the folders' names. The second part iterates through all the folders beneath the folder called Personal Folders and displays their names.

You can include this type of iteration in a logon script to enhance users' daily interface with Outlook. For example, you can write a logon script that sends users a notice specifying how many new messages have arrived since they logged off, how many of those messages are urgent, who sent the urgent messages, and the urgent messages' subject lines.

Listing 5, page 5, contains an example logon script. After the script creates the reference to an InBox object (objInBox), the script applies the For Each...Next statement to iterate through all the items in the InBox folder. The script uses two If...Then statements to increment the intNewMail counter for every unread message and the intUrgentMail counter for every unread urgent message. For each urgent message, the script adds the sender's name and the subject line to the output string. Finally, the script prints the output string.

You can manipulate other folders besides the InBox. For example, if you want to send an message to everyone in your Contacts folder, you can iterate through the Contacts folder. As Listing 6 shows, the script to iterate through this folder is similar to the script to iterate through the InBox folder (Listing 5), except that the properties differ. In Listing 6, the script creates a reference to a new message (objMail) and to the Contacts folder (objFolder). The script then iterates through the Contacts folder, checking each contact for an email address (i.e., the Email1Address property). If the contact has an email address, the script adds the contact's full name to the message's To field. (You don't have to initialize the To field, because initialization automatically occurs when the script creates the message.) The script separates the email addresses with semicolons; the semicolon before the first address doesn't hamper the script's execution. After the script sets the other message options, it sends the message.

You can adapt this script in many ways. For example, you can have the script search each contact for more properties so that only certain people in your Contacts folder receive the message. You can also adapt the script to iterate through any address book in the current profile rather than the Contacts folder. You simply access the AddressLists collection object directly from the MAPI reference to get the collection of address books (i.e., AddressLists collection object). You then iterate through this collection to access each address book (i.e., AddressEntries collection object). Finally, you iterate through that address book to search for individual addresses (i.e., AddressEntry objects).

Creating and Delegating a Task
In Outlook, you can attach an appointment, meeting, or task request to an email message. The email recipients, in turn, can use the attached request to automatically schedule the appointment, meeting, or task. For example, suppose you want to use email to delegate a task to Keith Cooper. Listing 7 shows how you can create and delegate a new task. You begin by creating a reference to the TaskItem object (objItem). To indicate that you're delegating the task, you use TaskItem's Assign method. You then use the Recipients collection object's Add method to specify Keith Cooper as the recipient.

Only Scratching the Surface
You have a wide array of objects, methods, and properties with which to automate Outlook messaging. I briefly touched on only a few of them. To learn more about automating Outlook and how to work with its many objects, methods, and properties, check out Sue Mosher's Slipstick Systems Web site ( and Microsoft's Web site for Outlook development ( Chapter 9 of Building Applications with Microsoft Outlook 98 (Microsoft Press, 1998) also contains useful basic documentation.