Sending Emails Using CDO in WSH

Whether you want start an in-house newsletter or you’d like email notification when machines log in and off of your network, there are plenty of reasons to incorporate emailing into your scripts.

In order to add email functionality to WSH, we’re going to have to make use of the Cdosys.dll library.  CDOSYS is an implementation of Collaborative Data Objects (CDO), formerly Active Messaging, a Microsoft technology for adding messaging capabilities to applications.  CDOSYS is available in Microsoft Windows 2000 and newer.  Older systems will need to use CDONTS.  Here’s a brief roadmap.  Note that this is not totally inclusive.  More details information can be found in MSKB 171440.

Name

Version

Library

ProgID

Release

Active Messaging

1.1

OLEMSG32.DLL

MAPI

Exchange 5.0

CDO 1.2.1

1.2.1

CDO.DLL

MAPI

Exchange 5.5, Outlook 98, Outlook 2000, Exchange 2000 Server

CDO 1.2 for Windows NT Server

1.2

CDONTS.DLL

CDONTS

Exchange 5.5, Windows NT 4.0 SP1, IIS 4.0, MCIS, Windows 2000 Server

CDO for Windows 2000

6.0

CDOSYS.DLL

CDO

Windows 2000 Server, Windows XP, Windows Server 2003

I’m assuming that most of you reading this will be using Windows 2000 or newer so I won’t be covering the use CDONTS.  If you are trying to implement CDONTS you can ask me questions in the article blog.  Since it is legacy and has several limitations I didn’t feel it warranted much attention, however, the syntax is very similar.

To begin, you’ll need to connect to the CDOSYS namespace by making a call to its ProgID.

Set objMessage = CreateObject("CDO.Message")

Next you’ll have to set your email fields, so let’s take a look at some syntax.  You should note that the CDO syntax is far beyond the scope of this article so I certainly won’t be covering the whole topic.  I’m only going to be covering the most common parts and the extras that I think would be most useful for the common reader.  You can find much more complete documentation on CDO 2.0 by visiting Microsoft’s MSDN site for CDO for Windows 2000.

{mospagebreak title=Preparing your message}

We’ll begin by setting our basic email fields: To, From, CC, BCC, etc.  These are the fields used to construct the email’s header.

Properties

object.To

object.From

object.CC

object.BCC

object.ReplyTo

object.Subject

object.Textbody

object.HTMLBody

object.Configuration.Fields.Item(schema)

 

Methods

object.Configuration.Fields.Update

object.CreateMHTMLBody htmlbody

object.AddAttachment file

object.Send

All of the properties listed above accept text strings and are used to set various email fields.  I’ll go into details about them as we use them.  These are much easier to learn when you see them in action.

Set objMessage = CreateObject("CDO.Message")

‘ Set Email Headers

objMessage.From = "sender@mymail.com"

objMessage.To = "recipient@mail.com"

objMessage.CC = "copyto@mail.com"

objMessage.BCC = "blindcopy@mail.com"

objMessage.ReplyTo = "replyto@mail.com"

objMessage.Subject = "Test email with CDOSYS!"

‘ Construct Email Body

objMessage.Textbody = "This is a test email using CDOSYS."

Here you can see I’ve set the standard email fields.  Only the From, To, and Textbody fields are required.  The ReplyTo field is the address that replies should be sent to if you don’t want them going to the From email address by default.

All of the email address fields may use any standard email address format:

  • "Full Name" <email@domain.com>
  • "Full Name" email@domain.com
  • Full Name <email@domain.com>
  • email@domain.com

You may add multiple recipients to any of the address fields by separating multiple addresses with commas.  If you use any of the formats involving quotation marks, you will need to escape them in your script.

The Textbody property accepts a single text string as a value.  This can have any number of carriage returns as needed.  The text string can be read from an existing text file, read from any TextStreamObject (such as a program’s output) or coded manually.

object.AddAttachment localpath | remoteurl[, username, password]

Want to add some attachments?  That’s no problem either.

objMessage.AddAttachment "C:attachment.txt"

AddAttachment can accept either a local file path or a valid URL.  If the URL is password protected, be sure to add the username and password as well.  You may call AddAttachments as many times as needed to add multiple attachments to your message.

{mospagebreak title=Configuring the SMTP server}

In order to send the message, CDO needs to know some information about the SMTP server you’ll be using to send it.  While this can be a local server, in most cases it’s probably going to be remote.

objEmail.Configuration.Fields.Item _

   ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2

objEmail.Configuration.Fields.Item _

   ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _

   "smtp.mymail.com"

objEmail.Configuration.Fields.Item _

("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25

The Configuration.Fields Property returns a collection of settings used to configure your email message (or newsgroup post as CDO also supports NNTP) for SMTP.  There is a long list of configurations available.  I’m only showing you the ones you’ll need most.

For more information I suggest checking out Chapter 6 of Brian Knittel’s book “Windows XP Under the Hood,” a fantastic Windows Scripting book available from Que.  The chapter, titled “Messaging Objects,” takes an in-depth look at the CDO object.  You can pick it up at both Barnes&Noble and Amazon.com.

The sendusing property will almost always be set to 2.  This tells CDO to send your message directly to the SMTP server that you provide.  A value of 1 would indicate to drop the message into the IIS SMTP service pickup directory instead.

The smtpserver item accepts either a valid hostname or IP address for the SMTP server.  The smtpserverport item should be set to whatever port your SMTP server operates on.  In most cases this is port 25.

If your SMTP server requires authentication, you’ll need to add a few more configuration fields.

objEmail.Configuration.Fields.Item _

("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1

objEmail.Configuration.Fields.Item _

   ("http://schemas.microsoft.com/cdo/configuration/sendusername") = _

   "user"

objEmail.Configuration.Fields.Item _

   ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = _

   "password"

The smtpauthenticate item accepts one of three cdoProtocolsAuthentication values.  Use its default 0 for no authentication, 1 for basic (clear-text) authentication, or 2 to use the credentials of the currently logged on user.

If your outgoing mail server requires a secure connection, you’ll also need to set the smtpusessl item.  It accepts a Boolean value and defaults to false.

objEmail.Configuration.Fields.Item _

   ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True

After setting all of the configuration items, you’ll need to make a call to the Update method in order to save those settings in the Fields collection.

objEmail.Configuration.Fields.Update

objEmail.Send

Finally, you can make a call to the CDO object’s Send method and send your message zipping off through cyberspace.  One nice thing about using CDOSYS instead of CDONTS is that you can use this as many times as necessary.  CDONTS only supports sending one message at a time and requires you to recycle the message object each time you need it.

{mospagebreak title=Sending HTML messages}

Okay, so sending text emails isn’t enough for you?  This is the age of modern email after all and in most cases you’ll want to send email with clickable links and embedded images.  In this case, you’ll want to send HTML formatted emails.

CDOSYS says “no problemo!”  It can handle those as well.  You’ll have two choices.  You can either send an HTML formatted text string or you can tell CDOSYS to send an HTML document as your email body.  The document can be either local or remote.

We’ll start with the first and send an HTML formatted text string.  You’re going to use the same email script we’ve just created.  This time you’re going to leave out the Textbody property and replace it with the appropriate HTML property or method.

object.HTMLbody

object.CreateMHTMLbody path [, flags [, username, password]]

The HTMLbody property returns or sets the HTML body part of your message.  The CreateMHTMLbody method will create an email message from the HTML document you specify.  The path may be remote or local but must be a full local path or a fully qualified URI.  The flags attribute accepts a constant value that tells the CDOSYS object what parts, if any, should be omitted from the message.  Finally, you may supply a username and password if the HTML document you specify is password protected.

Fully qualified URIs must begin with a valid protocol.  Here are common examples:

  • http://www.mysite.com/index.html
  • file:///C:/pages/index.htm

So if we wanted to send our local HTML page, we would change our script by replacing the first section of code with the section below.  All I’ve done is removed the line setting the Textbody property and replaced it with a line that sets the HTMLbody property instead.  Of course, I’ve formatted the text in HTML as well.

Set objMessage = CreateObject("CDO.Message")

‘ Set Email Headers

objMessage.From = "sender@mymail.com"

objMessage.To = "recipient@mail.com"

objMessage.CC = "copyto@mail.com"

objMessage.BCC = "blindcopy@mail.com"

objMessage.ReplyTo = "replyto@mail.com"

objMessage.Subject = "Test email with CDOSYS!"

‘ Construct Email Body

objMessage.HTMLbody = "<h1>This is a test email using CDOSYS.</h1>"

To send a local or remote HTML document, we would replace the same line with a call to the CreateMHTMLbody method instead.  Here’s an example of what that code might look like.

Set objMessage = CreateObject("CDO.Message")

‘ Set Email Headers

objMessage.From = "sender@mymail.com"

objMessage.To = "recipient@mail.com"

objMessage.CC = "copyto@mail.com"

objMessage.BCC = "blindcopy@mail.com"

objMessage.ReplyTo = "replyto@mail.com"

objMessage.Subject = "Test email with CDOSYS!"

‘ Construct Email Body

objMessage.CreateMHTMLbody "C:pagesindex.htm"

The rest of your script would remain exactly the same.  However, sending HTML messages does raise one problem.  Some people are still using email clients that do not support HTML messages.

In those cases your may want to send what’s known as a multi-part message that includes both an HTML and a plain text portion.  In this case, the HTML is displayed by default, and the plain text is displayed whenever HTML is not supported. 

CDOSYS makes sending multi-format messages very easy.  Just add the following line and let the AutoGenerateTextBody property do the rest.

objMessage.AutoGenerateTextBody = True

The AutoGenerateTextBody property tells CDOSYS whether or not to auto-generate a multi-format message by creating a text portion from the HTML part that you have provided.  Its default is False.

You now have everything you need to send email messages in WSH.  Keep in mind that the CDO objects do provide much more functionality than I have been able to include in this article.  You can request Deliver Service Notifications and Read Receipts, check local email boxes, access local Address Books, check and post to newsgroups, and more.  Unfortunately, I don’t have enough room to cover it all, so I’m forced to wrap this up.  Until next time, keep coding!

6 thoughts on “Sending Emails Using CDO in WSH

  1. In this article I’m going to show you how to add email capabilities to your scripts without the need for third-party programs. Hope you enjoy.

[gp-comments width="770" linklove="off" ]