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

Comments (6)

  1. Tom says:

    This is definitely an older way of doing it. A new option (>= PowerShell 5): https://blogs.technet.microsoft.com/ccarroll/2017/11/28/use-powershell-to-send-email-from-o365-account/

    1. Yes, indeed. The Send-MailMessage cmdlet is what I use in several other places. 🙂

    1. The primary answer is in my example, I needed to set specific X-headers to test transport rules (which I have since updated to make more clear–sometimes all the thoughts in my head don’t make it all the way to paper). In the System.Net.Mail.MailMessage class, we have the ability to construct and manipulate headers, which I dn’t think the Send-MailMessage cmdlet has.

      If only someone would PUT IT ALL TOGETHER.

  2. SF says:

    Nice script. Improvement idea > after sending the email successfully, copy it to the “sent items” folder of the account which is used to authenticate.
    many moons back, I was looking for a similar script & needed the option to see sent emails.

    G****e implements this in their SMTP server ( which is not in the SMTP specifications ) and I had a tough time convincing the customer to move their application email from G to an exchange server. eventually moved it to a script which used EWS instead of SMTP and has this capability.

    1. That would definitely be cool to add. I’ve done a bit of EWS work in the past (though I am by no means an EWS expert). 🙂

Skip to main content