public/Send-HtmlMailMessage.ps1
function Send-HtmlMailMessage { <# .SYNOPSIS Sends a nicely formatted HTML email. .DESCRIPTION Sends a nicely formatted HTML email. This cmdlet is designed to work just like Send-MailMessage, with -Heading, -Body, -BodyFormatted, and -Footer replacing the default -Body of Send-MailMessage. .INPUTS No inputs .OUTPUTS No outputs .EXAMPLE Send-HtmlMailMessage -From "server01@contoso.com" -To "admin@contoso.com" .LINK https://github.com/natescherer/PoshEmail #> [CmdletBinding(DefaultParameterSetName = "Default")] param( [parameter(ParameterSetName = "Default", Mandatory = $true)] [parameter(ParameterSetName = "Button", Mandatory = $true)] # Specifies the address from which the mail is sent. Can either be an email address, or, optionally, a name # and email address combo in the format 'Someone <someone@example.com>' [string]$From, [parameter(ParameterSetName = "Default", Mandatory = $true)] [parameter(ParameterSetName = "Button", Mandatory = $true)] # Specifies the subject of the email message. This parameter is required. [string]$Subject, [parameter(ParameterSetName = "Default", Mandatory = $true)] [parameter(ParameterSetName = "Button", Mandatory = $true)] # Specifies the addresses to which the mail is sent. Can either be an email address, or, optionally, a name # and email address combo in the format 'Someone <someone@example.com>' [string[]]$To, [parameter(ParameterSetName = "Default", Mandatory = $true)] [parameter(ParameterSetName = "Button", Mandatory = $true)] [ValidateNotNullOrEmpty()] # Specifies a string to use as the body of the message. # If you have a multi-paragraph body, wrapped each paragraph as follows: # - <p>Paragraph 1</p><p>Paragraph 2</p> # If you want to include preformatted data, it is recommended to use the -BodyPreformatted attribute # for that. [string]$Body, [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateSet("Left", "Center", "Right")] # Specifies how the body should be aligned. The acceptable values for this parameter are: # - Left # - Center # - Right # Left is the default. [string]$BodyAlignment = "Left", [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateNotNullOrEmpty()] # Specifies a string of preformmated text (code, cmdlet output, etc) to include below the body of the message. # This will be displayed either in a horizontally-scrolling box or, if Outlook (which can't support # scrolling) wrapped with line numbers. [string]$BodyPreformatted = "", [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateNotNullOrEmpty()] # Specifies the path to files to attach to the message. [string[]]$Attachments, [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateNotNullOrEmpty()] # Specifies the email addresses that receive a copy of the mail but are not listed as recipients of the # message. Can either be an email address, or, optionally, a name and email address combo in the format # 'Someone <someone@example.com>' [string[]]$Bcc, [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateNotNullOrEmpty()] # Specifies the email addresses to which a carbon copy (CC) of the email message is sent. Can either be # an email address, or, optionally, a name and email address combo in the format # 'Someone <someone@example.com>'. [string[]]$Cc, [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateNotNullOrEmpty()] # Specifies a PSCredential object, containing credentials used to send the message. [pscredential]$Credential, [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateSet("None", "OnSuccess", "OnFailure", "Delay", "Never")] # Specifies the delivery notification options for the email message. # The acceptable values for this parameter are: # - None. No notification. # - OnSuccess. Notify if the delivery is successful. # - OnFailure. Notify if the delivery is unsuccessful. # - Delay. Notify if the delivery is delayed. # - Never. Never notify. # None is the default. [string]$DeliveryNotificationOption, [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateSet("ASCII", "UTF8", "UTF7", "UTF32", "Unicode", "BigEndianUnicode", "Default", "OEM")] # Specifies the encoding used for the body and subject. The acceptable values for this parameter are: # - ASCII # - UTF8 # - UTF7 # - UTF32 # - Unicode # - BigEndianUnicode # - Default # - OEM # UTF8 is the default. [string]$Encoding = "UTF8", [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateNotNull()] # Specifies the port on which to connect to the SMTP server. # Defaults to 587. [int]$Port, [parameter(ParameterSetName = "Default", Mandatory = $true)] [parameter(ParameterSetName = "Button", Mandatory = $true)] [ValidateNotNullOrEmpty()] # Specifies the FQDN or IP address of the SMTP server that will send the message. [string]$SmtpServer, [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateSet("High", "Normal", "Low")] # Specifies the priority of the email message. The acceptable values for this parameter are: # - Normal # - High # - Low # Normal is the default. [string]$Priority, [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateNotNull()] # Specifies a string (with optional HTML formatting) to include in the heading of the message. [string]$Heading = "", [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateSet("Left", "Center", "Right")] # Specifies how the heading should be aligned. The acceptable values for this parameter are: # - Left # - Center # - Right # Center is the default. [string]$HeadingAlignment = "Center", [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateNotNull()] # Specifies a string (with optional HTML formatting) to include in the footer of the message. [string]$Footer = "", [parameter(ParameterSetName = "Button", Mandatory = $true)] [ValidateNotNullOrEmpty()] # Specifies a string to use as label for an optional button. [string]$ButtonText, [parameter(ParameterSetName = "Button", Mandatory = $true)] [ValidateNotNullOrEmpty()] # Specifies a link to use as a target for an optional button. [string]$ButtonLink, [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateSet("Left", "Center", "Right")] # Specifies how the button should be aligned. The acceptable values for this parameter are: # - Left # - Center # - Right # Center is the default. [string]$ButtonAlignment = "Center", [parameter(ParameterSetName = "Default", Mandatory = $false)] [parameter(ParameterSetName = "Button", Mandatory = $false)] [ValidateScript({ (![string]::IsNullOrEmpty($_.BodyTextColor)) -and (![string]::IsNullOrEmpty($_.BackgroundColor)) -and (![string]::IsNullOrEmpty($_.ContainerColor)) -and (![string]::IsNullOrEmpty($_.HeadingTextColor)) -and (![string]::IsNullOrEmpty($_.FooterTextColor)) -and (![string]::IsNullOrEmpty($_.LinkColor)) -and (![string]::IsNullOrEmpty($_.ButtonColor)) -and (![string]::IsNullOrEmpty($_.ButtonTextColor)) })] # Specifies a hashtable containing a color scheme if you wish to use non-default colors. [hashtable]$ColorScheme = @{ BodyTextColor = "#000000" BackgroundColor = "#f6f6f6" ContainerColor = "#ffffff" HeadingTextColor = "#000000" FooterTextColor = "#999999" LinkColor = "#999999" ButtonColor = "#3498db" ButtonTextColor = "#ffffff" } ) $NL = [System.Environment]::NewLine if ($BodyPreformatted) { $BodyWidth = "1800" } else { $BodyWidth = "580" } $HtmlTop = ("<!doctype html>$NL" + "<html>$NL" + " <head>$NL" + " <meta name=`"viewport`" content=`"width=device-width`">$NL" + " <meta http-equiv=`"Content-Type`" content=`"text/html; charset=UTF-8`">$NL" + " <title></title>$NL" + " <style>$NL" + " /* -------------------------------------$NL" + " INLINED WITH htmlemail.io/inline$NL" + " ------------------------------------- */$NL" + " /* -------------------------------------$NL" + " RESPONSIVE AND MOBILE FRIENDLY STYLES$NL" + " ------------------------------------- */$NL" + " @media only screen and (max-width: 620px) {$NL" + " table[class=body] h1 {$NL" + " font-size: 28px !important;$NL" + " margin-bottom: 10px !important;$NL" + " }$NL" + " table[class=body] p,$NL" + " table[class=body] ul,$NL" + " table[class=body] ol,$NL" + " table[class=body] td,$NL" + " table[class=body] span,$NL" + " table[class=body] a {$NL" + " font-size: 16px !important;$NL" + " }$NL" + " table[class=body] .preformatted {$NL" + " font-size: 11px !important;$NL" + " }$NL" + " table[class=body] .wrapper,$NL" + " table[class=body] .article {$NL" + " padding: 10px !important;$NL" + " }$NL" + " table[class=body] .content {$NL" + " padding: 0 !important;$NL" + " }$NL" + " table[class=body] .container {$NL" + " padding: 0 !important;$NL" + " width: 100% !important;$NL" + " }$NL" + " table[class=body] .main {$NL" + " border-left-width: 0 !important;$NL" + " border-radius: 0 !important;$NL" + " border-right-width: 0 !important;$NL" + " }$NL" + " table[class=body] .btn table {$NL" + " width: 100% !important;$NL" + " }$NL" + " table[class=body] .btn a {$NL" + " width: 100% !important;$NL" + " }$NL" + " table[class=body] .img-responsive {$NL" + " height: auto !important;$NL" + " max-width: 100% !important;$NL" + " width: auto !important;$NL" + " }$NL" + " }$NL" + "$NL" + " /* -------------------------------------$NL" + " PRESERVE THESE STYLES IN THE HEAD$NL" + " ------------------------------------- */$NL" + " @media all {$NL" + " .ExternalClass {$NL" + " width: 100%;$NL" + " }$NL" + " .ExternalClass,$NL" + " .ExternalClass p,$NL" + " .ExternalClass span,$NL" + " .ExternalClass font,$NL" + " .ExternalClass td,$NL" + " .ExternalClass div {$NL" + " line-height: 100%;$NL" + " }$NL" + " .btn-primary table td:hover {$NL" + " background-color: $($ColorScheme.ButtonColor) !important;$NL" + " }$NL" + " .btn-primary a:hover {$NL" + " background-color: $($ColorScheme.ButtonColor) !important;$NL" + " border-color: $($ColorScheme.ButtonColor) !important;$NL" + " }$NL" + " }$NL" + " </style>$NL" + " </head>$NL" + " <body class=`"`" style=`"background-color: $($ColorScheme.BackgroundColor); font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;`">$NL" + " <table border=`"0`" cellpadding=`"0`" cellspacing=`"0`" class=`"body`" style=`"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: $($ColorScheme.BackgroundColor);`">$NL" + " <tr>$NL" + " <td style=`"font-family: sans-serif; font-size: 14px; vertical-align: top;`"> </td>$NL" + " <td class=`"container`" style=`"font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; margin: 0 auto; max-width: $($BodyWidth)px; padding: 10px;`">$NL" + " <div class=`"content`" style=`"box-sizing: border-box; display: block; margin: 0 auto; max-width: 100%; padding: 10px;`">$NL" + "$NL" + " <!-- START CENTERED CONTAINER -->$NL" + " <span class=`"preheader`" style=`"color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;`"></span>$NL" + " <table class=`"main`" style=`"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: $($ColorScheme.ContainerColor); border-radius: 3px;`">$NL" + "$NL" + " <!-- START MAIN CONTENT AREA -->$NL" + " <tr>$NL" + " <td class=`"wrapper`" style=`"font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;`">$NL" + " <table border=`"0`" cellpadding=`"0`" cellspacing=`"0`" style=`"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;`">$NL" + " <tr>$NL" + " <td style=`"font-family: sans-serif; font-size: 14px; vertical-align: top;`">$NL") $HtmlButton = (" <table border=`"0`" cellpadding=`"0`" cellspacing=`"0`" class=`"btn btn-primary`" style=`"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box;`">$NL" + " <tbody>$NL" + " <tr>$NL" + " <td align=`"$($ButtonAlignment.ToLower())`" style=`"font-family: sans-serif; font-size: 14px; vertical-align: top; padding-bottom: 15px;`">$NL" + " <table border=`"0`" cellpadding=`"0`" cellspacing=`"0`" style=`"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;`">$NL" + " <tbody>$NL" + " <tr>$NL" + " <td style=`"font-family: sans-serif; font-size: 14px; vertical-align: top; background-color: $($ColorScheme.ButtonColor); border-radius: 5px; text-align: center;`"> <a href=`"$ButtonLink`" target=`"_blank`" style=`"display: inline-block; color: $($ColorScheme.ButtonTextColor); background-color: $($ColorScheme.ButtonColor); border: solid 1px $($ColorScheme.ButtonColor); border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px; text-transform: capitalize; border-color: $($ColorScheme.ButtonColor);`">$ButtonText</a> </td>$NL" + " </tr>$NL" + " </tbody>$NL" + " </table>$NL" + " </td>$NL" + " </tr>$NL" + " </tbody>$NL" + " </table>$NL") $HtmlDataToFooter = (" </td>$NL" + " </tr>$NL" + " </table>$NL" + " </td>$NL" + " </tr>$NL" + "$NL" + " <!-- END MAIN CONTENT AREA -->$NL" + " </table>$NL" + "$NL" + " <!-- START FOOTER -->$NL" + " <div class=`"footer`" style=`"clear: both; margin-top: 10px; text-align: center; width: 100%;`">$NL" + " <table border=`"0`" cellpadding=`"0`" cellspacing=`"0`" style=`"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;`">$NL" + " <tr>$NL" + " <td class=`"content-block`" style=`"font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; font-size: 12px; color: $($ColorScheme.FooterTextColor); text-align: center;`">$NL") $HtmlBottom = (" </td>$NL" + " </tr>$NL" + " </table>$NL" + " </div>$NL" + " <!-- END FOOTER -->$NL" + "$NL" + " <!-- END CENTERED CONTAINER -->$NL" + " </div>$NL" + " </td>$NL" + " <td style=`"font-family: sans-serif; font-size: 14px; vertical-align: top;`"> </td>$NL" + " </tr>$NL" + " </table>$NL" + " </body>$NL" + "</html>$NL") if (!$ButtonText) { $HtmlButton = "" } $Heading = " <h2 style=`"text-align: $($HeadingAlignment.ToLower()); color: $($ColorScheme.HeadingTextColor);`">$Heading</h2>$NL" if ($Body -notlike "*<p>*") { $Body = "<p>$Body</p>" } if ($Body -like "*<table>*") { $Body = $Body -replace '<table>', '<table cellpadding="5" style="border-collapse: collapse; border: 1px solid black;">' $Body = $Body -replace '<th>', '<th style="background-color: gray; border: 1px solid black;">' $Body = $Body -replace '<td>', '<td style="border: 1px solid black;">' } if ($Footer) { $Footer = " $Footer$NL" } $Body = $Body -replace "<p>", " <p style=`"font-family: sans-serif; font-size: 14px; font-weight: normal; color: $($ColorScheme.BodyTextColor); margin: 0; margin-bottom: 15px; text-align: $($BodyAlignment.ToLower());`">" $Body = $Body -replace "</p>", "</p>$NL" if ($BodyPreformatted -ne "") { $BodyReformatted = "" foreach ($Line in $BodyPreformatted -split $NL) { $Line = $Line -replace " ", " " $BodyReformatted += " <li style=`"color: #4169E1; font-family: monospace; font-size: 11px;`"><span class=`"preformatted`" style=`"color: black; font-family: monospace; font-size: 11px; white-space: pre-wrap;`">$Line</span></li>$NL" } $BodyPreformatted = (" </td>$NL" + " </tr>$NL" + " <tr>$NL" + " <td class=`"preformatted`" width=`"100%`" style=`"font-size: 14px; vertical-align: top; max-width: 100%; overflow: auto; padding-top: 15px; padding-right: 15px;background-color: #F5F5F5; border: 1px solid black;`">$NL" + " <ol class=`"preformatted`">$NL" + "$BodyReformatted" + " </ol>$NL") $BodyPreformatted = $BodyPreformatted + (" </td>$NL" + " </tr>$NL" + " <tr>$NL" + " <td style=`"font-family: sans-serif; font-size: 14px; vertical-align: top;`">$NL" + " <p style=`"font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px; text-align: $($BodyAlignment.ToLower());`"> </p>$NL") } $Body = $Body -replace "<a ", "<a style=`"text-decoration: underline; color: $($ColorScheme.LinkColor); font-size: 16px; text-align: center;`" " $Footer = $Footer -replace "<a ", "<a style=`"text-decoration: underline; color: #999999; font-size: 12px; text-align: center;`" " $CompleteBody = $HtmlTop + $Heading + $Body + $BodyPreformatted + $HtmlButton + $HtmlDataToFooter + $Footer + $HtmlBottom $MessageParams = @{ SmtpServer = $SmtpServer Port = $Port From = $From To = $To Subject = $Subject HTML = $CompleteBody Encoding = $Encoding } if ($Attachments) { $MessageParams += @{Attachments = $Attachments } } if ($Bcc) { $MessageParams += @{Bcc = $Bcc } } if ($Cc) { $MessageParams += @{Cc = $Cc } } if ($Credential) { $MessageParams += @{Credential = $Credential } } if ($DeliveryNotificationOption) { $MessageParams += @{DeliveryNotificationOption = $DeliveryNotificationOption } } if ($Priority) { $MessageParams += @{Priority = $Priority } } Send-EmailMessage @MessageParams } |