Send Authenticated SMTP with PowerShell

Today, while I was testing out some transport rules, I wanted to send a bunch of test messages to make sure they were firing correctly.  I wanted to create some custom messages and be able to automate them, and I wanted to use an outside relay service that requires SMTP authentication.

It took a good bit of tinkering, but here's what I cobbled together:

 # Sender and Recipient Info
$MailFrom = "sender@senderdomain.com"
$MailTo = "recipient@recipientdomain.com"

# Sender Credentials
$Username = "SomeUsername@SomeDomain.com"
$Password = "SomePassword"

# Server Info
$SmtpServer = "smtp.domain.com"
$SmtpPort = "2525"

# Message stuff
$MessageSubject = "Live your best life now" 
$Message = New-Object System.Net.Mail.MailMessage $MailFrom,$MailTo
$Message.IsBodyHTML = $true
$Message.Subject = $MessageSubject
$Message.Body = @'
<!DOCTYPE html>
<html>
<head>
</head>
<body>
This is a test message to trigger an ETR.
</body>
</html>
'@

# Construct the SMTP client object, credentials, and send
$Smtp = New-Object Net.Mail.SmtpClient($SmtpServer,$SmtpPort)
$Smtp.EnableSsl = $true
$Smtp.Credentials = New-Object System.Net.NetworkCredential($Username,$Password)
$Smtp.Send($Message)

There's a few other interesting properties to the message and ways to get them in there.  As I am wont to do, I like to dig and poke around:

As you see, there are are plenty of things you can do.  Want to add an attachment?  Easy as pie:

 $Message.Attachments.Add("C:\Temp\pie.txt")
$Message.Attachments.Add("C:\Temp\pie2.txt")

Of course, maybe you didn't want to share both pie recipes.  I know how you are.  You can remove them (though it's not quite as intuitive, at least when I've tried to do it).

 $Message.Attachments.RemoveAt("0") # Remove the attachment at index 0
$Message.Attachments.RemoveAt("1") # Remove the attachment at index 1

One of the interesting properties that we have available is Headers.  The MSDN documentation doesn't have too much on it, but if you want to use it to add a custom header, you can use the ... wait for it ... Add method:

 $Message.Headers.Add("X-My-Test-Header","SomeData")

In this example, I populated $Message.Body with a Here-String.  If you have a larger HTML message body, you can also import it using Get-Content:

 $Message.Body = Get-Content htmlemail.html

And yes, I'm familiar with Send-MailMessage.  One of the things it doesn't have is the ability to modify message headers, so when you absolutely, positively need to emulate some very specific parameters or settings, accept no substitutes.

Hopefully this is helpful to someone out there in the universe.  If not, just disregard as the ramblings of an increasingly older man.

And