Send Email Using CDO.Message Object With Attachment
How to Send Email Using the CDO.Message Object With an Attachment
Collaboration Data Objects (CDO) is a long-standing Windows component for sending email from scripts and classic applications. If you work with VBScript, Classic ASP, or VBA, CDO.Message lets you send a message through an SMTP server, attach files such as PDF reports, and do it all without installing extra libraries.
This post shows how to send email using the CDO.Message object with an attachment, explains every configuration field, and covers the common problems you may run into.
What Is CDO.Message?
CDO.Message is a COM object that represents a single email message. You create it, configure how it connects to an SMTP server, fill in the sender, recipient, subject, body, and attachments, and then call Send.
Typical use cases include:
- Emailing generated PDF reports from scheduled scripts
- Sending notifications from Classic ASP pages
- Automating email from Excel or Access VBA macros
The Complete Code
vbscript
Const cdoSchema = "http://schemas.microsoft.com/cdo/configuration/"
Dim Mail
Set Mail = CreateObject("CDO.Message")
' --- Remote SMTP server configuration ---
' Send the message using the network (SMTP over the network)
Mail.Configuration.Fields.Item(cdoSchema & "sendusing") = 2
' SMTP server name and port
Mail.Configuration.Fields.Item(cdoSchema & "smtpserver") = "smtp.abc.com"
Mail.Configuration.Fields.Item(cdoSchema & "smtpserverport") = 25
' Use SSL for the connection (True or False)
Mail.Configuration.Fields.Item(cdoSchema & "smtpusessl") = False
' Connection timeout in seconds
Mail.Configuration.Fields.Item(cdoSchema & "smtpconnectiontimeout") = 60
' Authentication: 0 = none, 1 = basic (clear text)
Mail.Configuration.Fields.Item(cdoSchema & "smtpauthenticate") = 1
Mail.Configuration.Fields.Item(cdoSchema & "sendusername") = "username"
Mail.Configuration.Fields.Item(cdoSchema & "sendpassword") = "password"
Mail.Configuration.Fields.Update
' --- End of SMTP configuration ---
' Message details
Mail.Subject = "Subject"
Mail.From = "from@gmail.com"
Mail.To = "to@gmail.com"
Mail.TextBody = "Body"
' Attachment
Mail.AddAttachment "FilePath" & FileName & ".pdf"
Mail.Send
Set Mail = NothingI made two small changes to the original snippet for readability. The long schema URL is stored in a constant so each line stays short, and strings are joined with &, which is the standard VBScript concatenation operator.
Step-by-Step Explanation
1. Create the CDO.Message object
vbscript
Set Mail = CreateObject("CDO.Message")This creates the message object. Everything else, including server settings, recipients, and attachments, is set through its properties and methods.
2. Choose how the message is sent
vbscript
Mail.Configuration.Fields.Item(cdoSchema & "sendusing") = 2The sendusing field controls the delivery method:
| Value | Meaning |
|---|---|
| 1 | Use the local SMTP service pickup directory |
| 2 | Send over the network to a remote SMTP server |
Value 2 is what you want when relaying through a mail provider such as smtp.abc.com.
3. Set the SMTP server and port
vbscript
Mail.Configuration.Fields.Item(cdoSchema & "smtpserver") = "smtp.abc.com"
Mail.Configuration.Fields.Item(cdoSchema & "smtpserverport") = 25Replace smtp.abc.com with your provider’s SMTP host. Port 25 is the traditional SMTP port, but many providers block or restrict it. Check your provider’s documentation for the recommended port.
4. Configure SSL
vbscript
Mail.Configuration.Fields.Item(cdoSchema & "smtpusessl") = FalseSet this to True if your provider requires an encrypted connection. When you enable SSL, you will usually also need to change the port to the one your provider specifies for secure connections (commonly 465).
5. Set a connection timeout
vbscript
Mail.Configuration.Fields.Item(cdoSchema & "smtpconnectiontimeout") = 60This is the number of seconds CDO waits for the server before giving up. Sixty seconds is a sensible default.
6. Provide authentication
vbscript
Mail.Configuration.Fields.Item(cdoSchema & "smtpauthenticate") = 1
Mail.Configuration.Fields.Item(cdoSchema & "sendusername") = "username"
Mail.Configuration.Fields.Item(cdoSchema & "sendpassword") = "password"Most SMTP servers require you to log in. Setting smtpauthenticate to 1 enables basic authentication, and the next two fields supply your credentials. Use 0 if your server accepts unauthenticated relay, which is typical only on internal networks.
7. Save the configuration
vbscript
Mail.Configuration.Fields.UpdateThis call is required. Without it, the settings you assigned are not applied.
8. Define the message
vbscript
Mail.Subject = "Subject"
Mail.From = "from@gmail.com"
Mail.To = "to@gmail.com"
Mail.TextBody = "Body"These properties set the subject, sender, recipient, and plain-text body. You can also use Mail.Cc, Mail.Bcc, and Mail.HTMLBody for HTML content.
9. Add the attachment
vbscript
Mail.AddAttachment "FilePath" & FileName & ".pdf"AddAttachment takes the full path of the file on disk. Call it once for each file you want to attach.
10. Send and clean up
vbscript
Mail.Send
Set Mail = NothingSend delivers the message. Setting the object to Nothing releases it from memory.
Make the Attachment Path Reliable
A frequent mistake is building the path without a separator between the folder and file name. If FilePath is C:\Reports and FileName is Invoice1001, the result is C:\ReportsInvoice1001.pdf, which doesn’t exist. Make sure the folder ends with a backslash:
vbscript
FilePath = "C:\Reports\"
FileName = "Invoice1001"
Mail.AddAttachment FilePath & FileName & ".pdf"You can also check that the file exists before attaching it:
vbscript
Dim fso, fullPath
Set fso = CreateObject("Scripting.FileSystemObject")
fullPath = FilePath & FileName & ".pdf"
If fso.FileExists(fullPath) Then
Mail.AddAttachment fullPath
Else
WScript.Echo "Attachment not found: " & fullPath
End IfSending Multiple Attachments and HTML Content
vbscript
Mail.AddAttachment "C:\Reports\Invoice1001.pdf"
Mail.AddAttachment "C:\Reports\Summary.xlsx"
Mail.HTMLBody = "<h3>Your report</h3><p>Please find the documents attached.</p>"When you set HTMLBody, CDO generates a plain-text alternative automatically unless you set TextBody yourself.
Add Error Handling
If the server is unreachable or credentials are wrong, Send raises an error. Catch it so you can log or report the problem:
vbscript
On Error Resume Next
Mail.Send
If Err.Number <> 0 Then
WScript.Echo "Email failed: " & Err.Description
Err.Clear
Else
WScript.Echo "Email sent successfully."
End If
On Error GoTo 0In Classic ASP, replace WScript.Echo with Response.Write. In VBA, use MsgBox or write to a log.
Common Errors and Fixes
“The transport failed to connect to the server.” The server name or port is wrong, a firewall is blocking the connection, or your provider doesn’t allow the port you chose. Verify the host and port, and test connectivity from the same machine.
“The server rejected one or more recipient addresses.” The SMTP server refused to relay. Check that authentication is enabled and the credentials are correct, and that your account is allowed to send from the From address.
“Could not access ‘CDO.Message’ object.” The file path to the attachment is invalid, or the account running the script can’t read the file. Confirm the path and file permissions.
Authentication fails with a Gmail account. Providers such as Gmail have moved away from allowing a plain account password for scripts. Use an app-specific password (with two-step verification enabled) or the provider’s recommended SMTP relay option, and check their current documentation, as requirements change.
Mail is sent but lands in spam. Make sure the From address belongs to the domain you are authorized to send from, and that your domain has proper SPF and DKIM records.
Security Tips
- Don’t hard-code passwords. Store credentials in a protected configuration file, environment variable, or secrets store instead of the script.
- Prefer an encrypted connection. Basic authentication sends credentials in clear text unless SSL is enabled, so turn
smtpusesslon whenever your provider supports it. - Validate input. If recipients or subjects come from user input, sanitize them to prevent header injection.
A Note on CDO Today
CDO is a legacy technology. It still works well for existing scripts, scheduled jobs, and Classic ASP applications, and it requires no extra installation on Windows. For new .NET projects, however, a modern library such as MailKit is generally a better choice because it supports current security standards more completely.
