Send SMTP email with authentication from PowerShell

Email is a good way to send notifications from your PowerShell scripts, and it’s super easy. You just need an SMTP server, and use Send-MailMessage:

Send-MailMessage -From "testscript@rcmtech.co.uk" -To "robin@rcmtech.co.uk" -Subject "Something interesting just happened" -Body "Here's the details about the interesting thing" -SmtpServer smtp.rcmtech.co.uk

You can even omit the -SmtpServer bit if you’ve previously set the $PSEmailServer preference variable.

However, what if you don’t have your own internal mailserver, and the only one available needs credentials? Many ISPs require authenticated SMTP now. Sure, Send-MailMessage has a -Credentials options, but these need to be in the form of a System.Management.Automation.PSCredential object. You can use Get-Credential to generate one of these:

Get-Credential -Message "Cough up" -Username "your_username"

But Get-Credential doesn’t have an option to accept the password as plain text, and storing a password as plain text is bad practice anyway. Thus Get-Credential, in the form used above, will create the right kind of object that you can feed into Send-MailMessage, but it does it in the wrong kind of way – via a pop up a box for you to type your password into, which isn’t that handy for use in unattended scripting.

So the clever way to do this is to create yourself an encrypted password file. You can do this as follows:

Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File -FilePath username@domain.net.securestring

Run the above, enter the password (which will be obscured with asterisks as you type it), and hit <Enter>. Now you’ve got a text file with an encrypted password in it. How does this work? Read-Host prompts for text, because we’ve used the -AsSecureString switch it returns the text entered as a System.Security.SecureString object. We then pass this to ConvertFrom-SecureString which takes that object and spits it out as text, encrypted with Windows Data Protection API (DPAPI). You can also use 128, 192 or 256-bit AES encryption.

So now we have the password in a file, and can use this to create a PSCredential object:

New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "username@myisp.net",(Get-Content -Path username@myisp.net.securestring | ConvertTo-SecureString)

So now shove the whole lot together, on one line (because we can, and bigger is better, right?):

Send-MailMessage -From "username@myisp.net" -To "robin@rcmtech.co.uk" -Subject "Something interesting just happened" -Body "Here's the details about the interesting thing" -SmtpServer smtp.myisp.net -Port 587 -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "username@myisp.net",(Get-Content -Path username@myisp.net.securestring | ConvertTo-SecureString))

But to make it easier to interpret, here’s the same thing broken down with variables:

$PSEmailServer = "smtp.myisp.net"
$SMTPPort = 587
$SMTPUsername = "username@myisp.net"
$EncryptedPasswordFile = "username@myisp.net.securestring"
$SecureStringPassword = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString
$EmailCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $SMTPUsername,$SecureStringPassword
$MailTo = "robin@rcmtech.co.uk"
$MailFrom = "username@myisp.net"
$MailSubject = "Something interesting just happened"
$MailBody = "Here's the details about the interesting thing"
Send-MailMessage -From $MailFrom -To $MailTo -Subject $MailSubject -Body $MailBody -Port $SMTPPort -Credential $EmailCredential

If your SMTP server requires it, you can also add -UseSsl to Send-MailMessage.

Caveat: If you use DPAPI, the encrypted password file can only be decrypted on the machine that it was encrypted on.

Also see the later post about how to send email via Yahoo Mail from PowerShell, including how to use a plain text password.

This entry was posted in PowerShell and tagged , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

2 Responses to Send SMTP email with authentication from PowerShell

  1. This was a great article. Thank-you!

  2. Pingback: Send email via Yahoo with PowerShell | Robin CM's IT Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s