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 "" -To "" -Subject "Something interesting just happened" -Body "Here's the details about the interesting thing" -SmtpServer

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

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 "",(Get-Content -Path | ConvertTo-SecureString)

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

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

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

$PSEmailServer = ""
$SMTPPort = 587
$SMTPUsername = ""
$EncryptedPasswordFile = ""
$SecureStringPassword = Get-Content -Path $EncryptedPasswordFile | ConvertTo-SecureString
$EmailCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $SMTPUsername,$SecureStringPassword
$MailTo = ""
$MailFrom = ""
$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.

4 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

  3. Black says:


    thank you, very good article.

    In my opinion DPAPI is not only machine specific but also user specific!


    • Black says:

      this means you have to do the ‘Read-Host …’ command with the same user running the send-mailmessage, if you want to run the send-mailmessage in a script as scheduled task think about it

Leave a Reply

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

You are commenting using your 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