|
| 1 | +<# |
| 2 | + .SYNOPSIS |
| 3 | + Sends an email notification using SMTP. |
| 4 | +
|
| 5 | + .DESCRIPTION |
| 6 | + This function facilitates email sending using specified SMTP server configurations, offering enhanced security features over the 'Send-MailMessage' cmdlet. It provides robust authentication options by supporting both direct credential input and |
| 7 | + PSCredential objects. Additionally, this function ensures secure email transmission through the enforcement of SSL/TLS protocols for SMTP connections and by handling passwords exclusively as secure strings. It also supports sending emails with |
| 8 | + attachments and HTML content, catering to a variety of messaging needs. |
| 9 | +
|
| 10 | + |
| 11 | + .PARAMETER EmailUsername |
| 12 | + The username for the SMTP server. |
| 13 | +
|
| 14 | + .PARAMETER EmailPassword |
| 15 | + The password for the SMTP server, should be passed as a secure string. |
| 16 | +
|
| 17 | + .PARAMETER Credential |
| 18 | + An optional PSCredential object that contains the user's credentials. |
| 19 | +
|
| 20 | + .PARAMETER From |
| 21 | + The email address of the sender. |
| 22 | +
|
| 23 | + .PARAMETER To |
| 24 | + An array of recipient email addresses. |
| 25 | +
|
| 26 | + .PARAMETER Cc |
| 27 | + An optional array of CC recipient email addresses. |
| 28 | +
|
| 29 | + .PARAMETER Subject |
| 30 | + The subject of the email. |
| 31 | +
|
| 32 | + .PARAMETER Body |
| 33 | + The body of the email. Can be plain text or HTML based on the IsBodyHtml flag. |
| 34 | +
|
| 35 | + .PARAMETER SMTPServer |
| 36 | + The SMTP server address. |
| 37 | +
|
| 38 | + .PARAMETER SMTPPort |
| 39 | + The port number of the SMTP server. Default is 587. |
| 40 | +
|
| 41 | + .PARAMETER Attachment |
| 42 | + An optional file path for an email attachment. |
| 43 | +
|
| 44 | + .PARAMETER IsBodyHtml |
| 45 | + A boolean indicating whether the email body should be treated as HTML. |
| 46 | +
|
| 47 | + .EXAMPLE |
| 48 | + PS C:\> Send-EmailNotification -Credential (Get-Credential) -From "sender@example.com" -To "receiver@example.com","other@example.com" -Subject "Test Email" -Body "This is a test email." -SMTPServer "smtp.example.com" -SMTPPort 587 |
| 49 | +
|
| 50 | + .EXAMPLE |
| 51 | + PS C:\> Send-EmailNotification -EmailUsername "sender@example.com" -EmailPassword (ConvertTo-SecureString "Passw0rd" -AsPlainText -Force) -From "sender@example.com" -To "receiver@example.com" -Subject "Hello" -Body "Welcome!" -SMTPServer "smtp.example.com" -SMTPPort 465 -IsBodyHtml $true |
| 52 | +
|
| 53 | + .NOTES |
| 54 | + This function requires appropriate network permissions to access the SMTP server. |
| 55 | +
|
| 56 | + .AUTHOR |
| 57 | + Blake Drumm (blakedrumm@microsoft.com) |
| 58 | +
|
| 59 | + .CREATED |
| 60 | + April 23rd, 2024 |
| 61 | +
|
| 62 | + .LASTMODIFIED |
| 63 | + April 30th, 2024 |
| 64 | +
|
| 65 | + .LINK |
| 66 | + My personal blog: https://blakedrumm.com/ |
| 67 | +#> |
| 68 | + |
| 69 | +#Email Function |
| 70 | +function Send-EmailNotification |
| 71 | +{ |
| 72 | + param |
| 73 | + ( |
| 74 | + [System.String]$EmailUsername, |
| 75 | + [System.Security.SecureString]$EmailPassword, |
| 76 | + [System.Management.Automation.PSCredential]$Credential, |
| 77 | + #Either utilize $Credential or $EmailUsername and $EmailPassword. |
| 78 | + [System.String]$From, |
| 79 | + [System.String[]]$To, |
| 80 | + [System.String[]]$Cc, |
| 81 | + [System.String]$Subject, |
| 82 | + [System.String]$Body, |
| 83 | + [System.String]$SMTPServer, |
| 84 | + [System.String]$SMTPPort = '587', |
| 85 | + [System.String]$Attachment, |
| 86 | + [boolean]$IsBodyHtml |
| 87 | + ) |
| 88 | + |
| 89 | +function Test-TCPConnection { |
| 90 | + [CmdletBinding()] |
| 91 | + param ( |
| 92 | + [string]$IPAddress, |
| 93 | + [int]$Port, |
| 94 | + [int]$Timeout = 1000, |
| 95 | + [int]$RetryCount = 3 |
| 96 | + ) |
| 97 | + |
| 98 | + $attempt = 0 |
| 99 | + while ($attempt -lt $RetryCount) { |
| 100 | + try { |
| 101 | + $tcpclient = New-Object System.Net.Sockets.TcpClient |
| 102 | + $connect = $tcpclient.BeginConnect($IPAddress, $Port, $null, $null) |
| 103 | + $wait = $connect.AsyncWaitHandle.WaitOne($Timeout, $false) |
| 104 | + if (!$wait) { |
| 105 | + throw "Connection timeout" |
| 106 | + } |
| 107 | + $tcpclient.EndConnect($connect) |
| 108 | + $tcpclient.Close() |
| 109 | + return $true |
| 110 | + } |
| 111 | + catch { |
| 112 | + $tcpclient.Close() |
| 113 | + if ($attempt -eq $RetryCount - 1) { |
| 114 | + if ($ErrorActionPreference -ne 'SilentlyContinue' -and $ErrorActionPreference -ne 'Ignore') { |
| 115 | + # If it's the last attempt and error action is not to ignore or silently continue, throw an exception |
| 116 | + throw "Failed to connect to $IPAddress on port $Port after $RetryCount attempts. Error: $_" |
| 117 | + } |
| 118 | + } |
| 119 | + Start-Sleep -Seconds 1 # Optional: sleep 1 second between retries |
| 120 | + } |
| 121 | + $attempt++ |
| 122 | + } |
| 123 | + return $false |
| 124 | +} |
| 125 | + |
| 126 | + try |
| 127 | + { |
| 128 | + # Start progress |
| 129 | + $progressParams = @{ |
| 130 | + Activity = "Sending Email" |
| 131 | + Status = "Preparing to send email" |
| 132 | + PercentComplete = 0 |
| 133 | + } |
| 134 | + Write-Progress @progressParams |
| 135 | + |
| 136 | + # Create a new MailMessage object |
| 137 | + $MailMessage = New-Object System.Net.Mail.MailMessage |
| 138 | + $MailMessage.From = $From |
| 139 | + $To.ForEach({ $MailMessage.To.Add($_) }) |
| 140 | + $Cc.ForEach({ $MailMessage.CC.Add($_) }) |
| 141 | + $MailMessage.Subject = $Subject |
| 142 | + $MailMessage.Body = $Body |
| 143 | + $MailMessage.IsBodyHtml = $IsBodyHtml |
| 144 | + |
| 145 | + # Handle attachment if specified |
| 146 | + if ($Attachment -ne $null -and $Attachment -ne '') |
| 147 | + { |
| 148 | + # Update progress |
| 149 | + $progressParams.Status = "Adding attachments" |
| 150 | + $progressParams.PercentComplete = 20 |
| 151 | + Write-Progress @progressParams |
| 152 | + $MailMessage.Attachments.Add((New-Object System.Net.Mail.Attachment($Attachment))) |
| 153 | + } |
| 154 | + else |
| 155 | + { |
| 156 | + # Update progress |
| 157 | + $progressParams.Status = "Not adding any attachments" |
| 158 | + $progressParams.PercentComplete = 20 |
| 159 | + Write-Progress @progressParams |
| 160 | + } |
| 161 | + |
| 162 | + # Update progress |
| 163 | + $progressParams.Status = "Setting up SMTP client to: $SMTPServer`:$SMTPPort" |
| 164 | + $progressParams.PercentComplete = 40 |
| 165 | + Write-Progress @progressParams |
| 166 | + |
| 167 | + # Example usage |
| 168 | + Test-TCPConnection -IPAddress $SMTPServer -Port $SMTPPort -ErrorAction Stop | Out-Null |
| 169 | + |
| 170 | + # Create SMTP client |
| 171 | + $SmtpClient = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort) |
| 172 | + $SmtpClient.EnableSsl = $true |
| 173 | + if ($Credential) |
| 174 | + { |
| 175 | + $SmtpClient.Credentials = $Credential |
| 176 | + } |
| 177 | + else |
| 178 | + { |
| 179 | + $SmtpClient.Credentials = New-Object System.Net.NetworkCredential($EmailUsername, $EmailPassword) |
| 180 | + } |
| 181 | + |
| 182 | + # Update progress |
| 183 | + $progressParams.Status = "Sending email" |
| 184 | + $progressParams.PercentComplete = 60 |
| 185 | + Write-Progress @progressParams |
| 186 | + |
| 187 | + # Send the email |
| 188 | + $SmtpClient.Send($MailMessage) |
| 189 | + |
| 190 | + # Final progress update |
| 191 | + $progressParams.Status = "Email sent successfully!" |
| 192 | + $progressParams.PercentComplete = 100 |
| 193 | + Write-Progress @progressParams |
| 194 | + Write-Output "Email sent successfully!" |
| 195 | + } |
| 196 | + catch |
| 197 | + { |
| 198 | + Write-Warning @" |
| 199 | +Exception while sending email notification. $_ |
| 200 | +"@ |
| 201 | + } |
| 202 | + finally |
| 203 | + { |
| 204 | + if ($MailMessage) |
| 205 | + { |
| 206 | + $MailMessage.Dispose() |
| 207 | + } |
| 208 | + if ($SmtpClient) |
| 209 | + { |
| 210 | + $SmtpClient.Dispose() |
| 211 | + } |
| 212 | + Write-Progress -Activity "Sending Email" -Status "Completed" -Completed |
| 213 | + } |
| 214 | +} |
| 215 | + |
| 216 | +#========================================================= |
| 217 | +# Example 1 |
| 218 | +Send-EmailNotification -Credential (Get-Credential) -From 'your-email@gmail.com' -To 'recipient-email@domain.com' -Subject "Subject Name" -Body "Hello!" -SmtpServer 'smtp.server.com' -SMTPPort 465 |
| 219 | + |
| 220 | +#========================================================= |
| 221 | +# Example 2 |
| 222 | +Send-EmailNotification -EmailUsername 'your-email@gmail.com' -EmailPassword (ConvertTo-SecureString 'yourpassword' -AsPlainText -Force) -From 'your-email@gmail.com' -To 'recipient-email@domain.com' -Subject "Subject Name" -Body @" |
| 223 | +Hello! |
| 224 | +
|
| 225 | +Welcome! |
| 226 | +"@ -SmtpServer 'smtp.server.com' |
| 227 | + |
| 228 | +#========================================================= |
0 commit comments