How to send a email via powershell

[June 27, 2014] Update: I’ve made several updates, including multiple recipients and sending attachments.

If you’ve created a PowerShell script that runs as a scheduled task, you may want to have it send you an e-mail with a log file or other notification about what the script did or didn’t do (i.e. error notification). PowerShell version 2 provides the Send-MailMessage cmdlet to do this, but in some cases the older System.Net.Mail .NET namespace is a more desirable approach (System.Net.Mail also works in PowerShell version 1).

The Send-MailMessage Method

Here is an example of the Send-MailMessage cmdlet:

1
2
3
4
5
6
7
8
9
$emailSmtpServer = "mail.somewhere.com"
$emailFrom = "John Smith <john@somewhere.com>"
$emailTo = "jane@somewhere.com"
$emailSubject = "Testing e-mail"
$emailBody = @"
Here is a message
From your friendly neighborhood IT guy
"@
Send-MailMessage -To $emailTo -From $emailFrom -Subject $emailSubject -Body $emailBody -SmtpServer $emailSmtpServer

Some notes:

  • On line 1, $emailSmtpServer is the mail server that you will be using to send the message.
  • On line 3, $emailFrom contains a friendly name (i.e. “John Smith”) followed by John’s e-mail addressed, enclosed in <>.

You can use HTML formatting in the $emailBody if you specify the -BodyAsHTML flag in the Send-MailMessage command, like this:

1
2
3
4
5
6
$emailBody = @"
<p>Here is a message that is <strong>HTML formatted</strong>.</p>
<p>From your friendly neighborhood IT guy</p>
"@
Send-MailMessage -To $emailTo -From $emailFrom -Subject $emailSubject -Body $emailBody -BodyAsHTML -SmtpServer $emailSmtpServer

That message will come out looking something like this:

Here is a message that is HTML formatted.

From your friendly neighborhood IT guy

If you need to send an attachment, change your Send-MailMessage command to something like this:

1
2
3
4
5
6
$attachment = "C:\myfile.txt"
#Or do multiple attachments like this:
$attachment = "C:\myfile1.txt","C:\myfile2.txt"
Send-MailMessage -To $emailTo -From $emailFrom -Subject $emailSubject -Body $emailBody -BodyAsHTML -Attachments $attachment -SmtpServer $emailSmtpServer

The System.Net.Mail Method

The Send-MailMessage method works well, if you have an SMTP server that does not require authentication and works on the standard SMTP port (port 25). If you need to send the message through an e-mail system such as GMail or Exchange Online which requires authentication and TLS on port 587, then using the System.Net.Mail .NET namespace is a good way to go.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$emailSmtpServer = "mail.somewhere.com"
$emailSmtpServerPort = "587"
$emailSmtpUser = "username"
$emailSmtpPass = "password"
$emailMessage = New-Object System.Net.Mail.MailMessage
$emailMessage.From = "John Smith <john@somewhere.com>"
$emailMessage.To.Add( "jane@somewhere.com" )
$emailMessage.Subject = "Testing e-mail"
$emailMessage.IsBodyHtml = $true
$emailMessage.Body = @"
<p>Here is a message that is <strong>HTML formatted</strong>.</p>
<p>From your friendly neighborhood IT guy</p>
"@
$SMTPClient = New-Object System.Net.Mail.SmtpClient( $emailSmtpServer , $emailSmtpServerPort )
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential( $emailSmtpUser , $emailSmtpPass );
$SMTPClient.Send( $emailMessage )

Essentially, what we are doing is building the mail message $emailMessage with its various components, building the $SMTPClient with the server and credential information, and then using that to send the mail message. This obviously takes some more code, but it is more flexible than the Send-MailMessage method.

To send attachments using this method, add this before the $SMTPClient.Send line:

1
2
$attachment = "C:\myfile.txt"
$emailMessage.Attachments.Add( $attachment )

For multiple attachments, just repeat those two lines of code, with the new file name.

Multiple Recipients

If you need to your message to multiple recipients, for the Send-MailMessage method:

1
$emailTo = "jane@somewhere.com","jim@somewhere.com"

For the System.Net.Mail method:

1
2
$emailMessage.To.Add( "jane@somewhere.com" )
$emailMessage.To.Add( "jim@somewhere.com" )

Here-Strings

On a side note, I’ve used a Here-String for the $emailBody variable. When sending a non-HTML formatted message, this allows you to easily insert line breaks without having to use `n notation. Even when sending an HTML formatted message, it makes it easier to read in your code.