The greatest challenge to any thinker is stating the problem in a way that will allow a solution

Bertrand Russell

By

On 7 Sep 2011

PowerShell, Tech Notes

Tags: , ,


Being able to send an email from a script is always a useful tool to have in your back pocket. Be it for sending out an alert for a bespoke check, an email over the weekend to let you know that that big task script has completed (un)successfully, a regular report mail, or some other reason.

Sending a basic text email is incredibly easy (2 lines), and it doesn’t take much more effort to be able to send fully formatted HTML email with attachments (though obviously you’ll need to put some effort into creating the HTML).

You will need an SMTP server to send your emails via. Your ISP will normally have one you can use (especially if you’ve an email account with them), or if your at work your email administrator will be able to let you know what to use. You may need to use a user/pass and/or need to connect from a pre-authorised IP address in order for your sending attempt to be accepted. Also if you’re sending attachments, bear in mid that most email systems restrict the size of emails that they will relay/accept, under 2MB is generally OK.

UPDATE: If you are using a later version of PowerShell (v2 onwards) then there is now a dedicated CmdLet for this:
Send-MailMessage.
Do a Get-Help on this command or see TechNet for further info.

SMTP Client

Its all achieved by using the .NET SMTPclient  class, and in its simplest form is done like this…

$smtpClient = New-Object Net.Mail.SmtpClient -arg $smtpServer
$smtpClient.Send("from@domain.com","to@domain.com","Email subject","Email body text")

…if you want to send to multiple addresses, comma seperate them.

If you need to use a user/pass in order to be able to relay through your SMTP server, you need to supply a credential object, for example…

$cred = new-object System.net.networkCredential
$cred.domain = "the domain you want"
$cred.userName = "username"
$cred.password = "password"
$smtp.credentials = $cred

Mail Message

For anything more than a small raw text email, it makes sense to construct a full MailMessage object , and send that. It exposes more functionality to you, the most useful of which being attachments and HTML (ie HTML format email contents so you can create formatted messages – if you don’t do HTML then you probably won’t want to use this.

To use a mail message…

$msg = New-Object Net.Mail.MailMessage
$msg.From = $emailFrom
$msg.To.Add($emailTo)
$msg.Subject = $emailSubject
$msg.Body = $msgBody
 
# Then send using a SMTP client, as before...
$smtpClient.Send($msg)

If you want to add an attachment…

$attach = New-Object Net.Mail.Attachment($File)
 
# Then attach to your mail message, and send as above
$msg.Attachments.Add($attach)

I have, on occasion had problems attaching a doc, as PowerShell couldn’t find it, as it wasn’t actually running in the same location as the where the resided, in this case I needed to use the following to find the file first…

((Get-Location -PSProvider FileSystem).ProviderPath) + "" + $OutputFile

If you want create some HTML for your email body you need to let the mail massage object know what to expect…

$msg.IsBodyHTML = $true

All Together Now

So, if you wanted to send an HTML email, with an attachment, and your SMTP server requires that you authenticate, you would do something similar to this…

# Required parameters
$smtpServer	# SMTP server hostname / IP address
$emailFrom	# Sender (some SMTP servers require a valid local address)
$emailRcpt	# Recipient (comma seperated if multiple)
$emailSubject	# Email subject line
$msgBody	# Email body
 
$FilePath	# Path to attachment file
 
$domain		# Network domain
$username	# Network username
$password	# Network password
 
# Create required objects...
$smtp = New-Object Net.Mail.SmtpClient -arg $smtpServer
$msg = New-Object Net.Mail.MailMessage
$attach = New-Object Net.Mail.Attachment($FilePath)
$cred = new-object System.net.networkCredential
 
# Populate mail message...
$msg.From = $emailFrom
$msg.To.Add($emailRcpt)
$msg.Subject = $emailSubject
$msg.IsBodyHTML = $true
$msg.Body = $msgBody
$msg.Attachments.Add($attach)
 
# Provide credentials to SMTP client
$cred.domain = "the domain you want"
$cred.userName = "username"
$cred.password = "password"
$smtp.credentials = $cred
 
# Send...
$smtp.Send($msg)

1 Comment to “Sending email from PowerShell”

  1. […] versions of PowerShell, so as an alternative you could use the .NET mail objects directly (see http://vblog.strutt.org.uk/2011/09/sending-email-from-powershell/ for more […]

Leave a Reply

XHTML: You can use these tags if you know what they are: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

ERROR: si-captcha.php plugin says GD image support not detected in PHP!

Contact your web host and ask them why GD image support is not enabled for PHP.

ERROR: si-captcha.php plugin says imagepng function not detected in PHP!

Contact your web host and ask them why imagepng function is not enabled for PHP.