Hi Everyone,
Today I wanted to show you my preferred way of sending custom HTML emails with PowerShell. There a ton of benefits to doing it this way. One of my favourites is the fact that you can embed images into the email rather than host them on a separate website.
I hope COVID restrictions are starting to ease for you all. Still, don’t want to let your guard down too much, ey! Better safe than sorry.
This article is also available on Medium if you prefer to read over there. You can find the link here!
Why bother ‘Sending Custom HTML Emails with PowerShell’?
The main issue with using custom HTML emails, is that HTML shows differently on every single device. This can result in your emails looking different with different email applications.
Outlook is particularly bad for displaying HTML in a uniform way. It often completely ignores the header which is often used to contain styling and CSS information. So the only way I’ve found around this is to include the styling on every single HTML element in the HTML body. This is far from ideal and takes a ton of time compared to header CSS styling.
The HTML Code
You can see the HTML code I used below. This includes every item of information and styling required for the email. It’s also were we set our content.
You can see in the HTML code, that I use it to:
- Set the Microsoft Office product details and pixel density information (This is required for Outlook)
- The logo.png is loaded using the cid: prefix which looks at the loaded images
- The rest is just generic HTML with inline styling
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="x-apple-disable-message-reformatting">
<title></title>
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
<style>
table,
td,
div,
h1,
p {
font-family: Arial, sans-serif;
}
</style>
</head>
<body style="margin:0;padding:0;">
<table role="presentation" style="width:100%;border-collapse:collapse;border:0;border-spacing:0">
<tr>
<td align="center" style="padding:0;">
<table role="presentation"
style="width:800px;border-collapse:collapse;border-spacing:0;text-align:left;">
<!--Logo-->
<tr>
<td align="center" style="padding:40px 0 10px 0">
<img src="cid:logo.png" alt="" width="350" style="height:auto;display:block;" />
</td>
</tr>
<tr>
<td style="padding:10px 10px 10px 10px;">
<table role="presentation"
style="width:100%;border-collapse:collapse;border:0;border-spacing:0;">
<!--First chunk-->
<tr>
<td style="padding:0 0 20px 0">
<h1
style="font-size:38px;margin:0 0 20px 0;font-family:Arial,sans-serif;text-align:center;">
Information Technology
</h1>
<p
style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;">
Dear $firstname,
</p>
<h2 style="font-size:22px;margin:0 0 10px 0;font-family:Arial,sans-serif">
Welcome!
</h2>
<p
style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;">
Generic text can go here
</p>
<h2 style="font-size:22px;margin:0 0 10px 0;font-family:Arial,sans-serif">
Your Login Information
</h2>
<p>
style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;">
More generic text
</p>
<p>
style="margin:0;font-size:16px;line-height:24px;font-family:Arial,sans-serif;">
</p>
</td>
</tr>
</table
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<!--Footer-->
<tr>
<td style="padding:30px;background:#272a36;">
<table role="presentation"
style="width:100%;border-collapse:collapse;border:0;border-spacing:0;font-size:9px;font-family:Arial,sans-serif;">
<tr>
<td style="padding:0;width:50%;" align="center">
<p style="margin:0;font-size:18px;line-height:16px;font-family:Arial,sans-serif;color:#ffffff;">
For an additional support, or if you have any questions, please
send an email to <a href="mailto:help@example.com"
style="color:#d6d6d6;text-decoration:underline;">help@example.com</a>
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
PowerShell
Now that we have the HTML configured with all the in-line CSS styling, the content and any required images, we can start looking into the actual PowerShell script. This is the actual ‘brains’ behind this task and it’s what we use to build the email object and send it over the internet.
The script requires the following input:
- The SMTP server
- Email from, to, bcc, subject and body objects
- The location of any images
- A try catch block to send the email
- Finally, dispose of the logo and email message objects
You can see this functionality in the below script. I hope it’s simple to follow as this is the most basic setup I could generate in order for the emails to function correctly:
#Define a valid SMTP server to send your emails through
$smtpServer = 'SERVER HERE' #e.g smtp.local.com
#Define a new SMTP object using the server defined above
$smtpObject = New-Object Net.Mail.SmtpClient($smtpServer)
#Create a new mail message object
$msg = New-Object Net.Mail.MailMessage
$msg.From = 'DoNotReply@example.com'
$msg.ReplyTo = 'bccemail@example.com'
$msg.BCC.Add('bccemail@example.com')
$msg.To.Add('recipient@example.com')
$msg.subject = 'Example Email Subject'
$msg.IsBodyHtml = $True
$msg.Body = 'HTML FROM ABOVE - This can be a separate variable or right here'
#Provide a path to the photos for the email
$scriptPath = 'C:\example'
#Create a new mail attachment as an image
$logo = New-Object System.Net.Mail.Attachment -ArgumentList "$scriptPath\logo.png"
$logo.ContentDisposition.Inline = $True
$logo.ContentDisposition.DispositionType = "Inline"
$logo.ContentType.MediaType = "image/png"
$logo.ContentId = 'logo.png'
#Add the image attachment to the email, this allows the HTML to use the cid: prefix
$msg.Attachments.Add($logo)
#Try to send the email
try{
$smtpObject.Send($msg)
}catch{
Write-Host 'Failed to send the email: ' -ForegroundColor Red -NoNewLine
Write-Host $Error[0] -ForegroundColor Red
}
#Dispose of the image attachments and the email object to avoid memory leaks
#logo.Dispose()
$msg.Dispose()
Finished!
That’s it, you now have the HTML and PowerShell code required to send custom HTML emails to basically any email application. As mentioned, this has been tested in Microsoft Outlook and functions perfectly.
Hopefully this shows just how easy it is to create and send HTML emails using PowerShell, including images send directly from the script instead of hosting them and suppling a web page URL.
If you have any questions etc, feel free to comment and I’ll help however I can.
Enjoy! 🎉
I know this is 3 years later, but you’ve got a typo in the powershell script
$smptObject.Send($msg) rather than smtp
This was very helpful though once I figured that out
Thanks Jonathan! I’d like to say I left that in to make sure you’re awake, but I can’t lie hahaha Have a great day
Appreciate this post. Will try it out