Sending E-mail from a PowerShell Script

GusGallowsSupport Escalation Engineer
CERTIFIED EXPERT
Published:
A lot of my scripts are used to compile data and then produce output. But what do you do with the output once it is created? You can save it to your local drive, have it saved on a file share, or send it via e-mail to SharePoint, public folders, or mailboxes. Today, we will focus on how to send the output to an e-mail address. In addition, we will put it to a functional use which will show you how to format your output in such a way that you will be outputting the results of another script directly to the body of the e-mail using HTML so your formatting is preserved.

I have scoured the internet for PowerShell v1.0 solutions to sending e-mail via PowerShell and the best solution I have found to date was a function from a site called JBs PowerShell written by by Jakob Bindslet (jakob@bindslet.dk) in December of 2007. The URL for the original print of this script is as follows:

http://mspowershell.blogspot.com/2007/12/send-smtpmail-update.html

I am going to break down his script and explain each part of it to the best of my ability and then give you an example, from one of my scripts, of how to use the function that goes a bit deeper with emphasis on sending the message using HTML so that your output is properly formatted.

The scenario:

You have just changed the format of your company’s primary SMTP address from a first Initial and last name @ domain.com (I.E. ggallows@domain.com) to first name dot last name @ domain.com (I.E. Gus.Gallows@domain.com) and you want to notify the users of their new address. The script we will be using will collect all mailboxes of type UserMailbox and then sending each one an E-mail explaining the change and letting them know what their new e-mail address is.

But first, let’s go over the Send-SMTPMail function:
 
#function to send email from a PowerShell v1.0 script, specifying optional arguments
                      function Send-SMTPmail($to, $from, $subject, $body, $attachment, $cc, $bcc, $port, $timeout, $smtpserver, [switch] $html, [switch] $alert) 
                      {
                          #first, you need to specify which smtp server you want to use as a mail relay. 
                      	#You must have rights to relay through this server with the account you are running the script from.
                      	#If you are an Exchange User, you should be able to use a HUB server in your environment.
                      	if ($smtpserver -eq $null) {$smtpserver = "smtpserver.domain.com"}
                      	#Now we can create the object which will allow us to use it as a mail client.
                          $mailer = new-object Net.Mail.SMTPclient($smtpserver)
                      	#The port defaults to 25, but can be set using the -port to whatever the SMTP port is on your SMTP server.
                          if ($port -ne $null) {$mailer.port = $port}
                      	#I am not sure what the default timeout is, but if you find it is inadequate, you can use the -timeout flag to change it.
                          if ($timeout -ne $null) {$mailer.timeout = $timeout}
                      	#Now we create the actual message object
                          $msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
                      	#if you want to send the message in HTML format, then you will need to use the -html flag.
                          if ($html) {$msg.IsBodyHTML = $true}
                      	#the cc (courtesy copy) flag is left blank unless you specify the -cc when you call the function
                          if ($cc -ne $null) {$msg.cc.add($cc)}
                      	#the bcc (blind courtesy copy) flag is left blank unless you specify the -bcc when you call the function
                          if ($bcc -ne $null) {$msg.bcc.add($bcc)}
                      	#If you set the alert flag, it will automatically set the standard sharepoint alert icon in outlook (if you are using outlook).
                          if ($alert) {$msg.Headers.Add("message-id", "<3bd50098e401463aa228377848493927-1>")}
                      	#if specifying an attachment, the following will create the attachment object and attach it to the message object.
                          if ($attachment -ne $null) {
                              $attachment = new-object Net.Mail.Attachment($attachment)
                              $msg.attachments.add($attachment)
                          }
                      	#the message is now completed and will send.
                          $mailer.send($msg)
                      }

Open in new window


Now, let's take a look at a functional use of the function. Using the following script, we will be able to grab a list of every UserMailbox in the domain, discover their Primary SMTP address, their First and Last name, and then send them a customized message in HTML format. If it seems long winded, it's because I want to include some HTML code in the body so I will show a couple of different tags.

This script assumes you are using the Exchange Management Shell on an Exchange 2007 environment.
The code looks as follows:
 
function Send-SMTPmail($to, $from, $subject, $body, $attachment, $cc, $bcc, $port, $timeout, $smtpserver, [switch] $html, [switch] $alert) 
                      {
                          if ($smtpserver -eq $null) {$smtpserver = "smtpserver.domain.com"}
                      	$mailer = new-object Net.Mail.SMTPclient($smtpserver)
                      	if ($port -ne $null) {$mailer.port = $port}
                      	if ($timeout -ne $null) {$mailer.timeout = $timeout}
                      	$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
                      	if ($html) {$msg.IsBodyHTML = $true}
                      	if ($cc -ne $null) {$msg.cc.add($cc)}
                      	if ($bcc -ne $null) {$msg.bcc.add($bcc)}
                      	if ($alert) {$msg.Headers.Add("message-id", "<3bd50098e401463aa228377848493927-1>")}
                      	if ($attachment -ne $null) {
                              $attachment = new-object Net.Mail.Attachment($attachment)
                              $msg.attachments.add($attachment)
                          }
                      	$mailer.send($msg)
                      }
                      #specify a domain controller in your environment where the mailboxes live. (A global catalog server should work well).
                      $dc = "dc1.domain.com"
                      #Gather all mailboxes of type UserMailbox into an array
                      $smbAll = Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited -DomainController $dc
                      #Iterate through each mailbox
                      for ($i = 0; $i -le ($smbAll.Length -1); $i +=1)
                      {
                      #assign a from address. You can use your address or if your relay allows it, a generic one.
                      #The rule usually is that it has to at least be from a valid relayable domain.
                      	$sFrom = "Do Not Reply - Notification Only <DoNotReply@domain.com>"
                      #Get the user's UserName
                      	$sUsername = Get-User $smbAll[$i] -domaincontroller $dc
                      #Get the User's PrimarySMTPAddress to use as the TO address
                      	$sTo = $smbAll[$i].PrimarySmtpAddress
                      #You may want to set a BCC address to a shared mailbox so you can easily confirm the message was delivered.
                      	$sbcc = "confirmMB@domain.com"
                      #Set the title of the message. In this case we are telling the user what their new PrimarySMTPAddress is.
                      	$sTitle = "Your new Email Address is $sTo (Do Not Reply to this message.)"
                      #Now for the fun part. Set the Body of the message. We are putting the whole content of the body between a set of double quotes
                      #so do not use double quotes anywhere else in your HTML. If you have to use quotes, use single quotes in the HTML.
                      	$sBody = "<p class=MsoNormal style='mso-line-height-alt:1.15pt'><span style='font-size:
                      	12.0pt;font-family:'Cambria','serif''>This past weekend, we implemented the new,
                      	standardized e-mail format for all employees. Your new primary
                      	e-mail address is now <a href='mailto:$sTo'>$sTo</a>.
                      	This is the e-mail address that will be seen by all external contacts and will
                      	be considered your 'primary' e-mail address. </span></p>
                      
                      	<p class=MsoNormal style='mso-line-height-alt:1.15pt'><span style='font-size:
                      	12.0pt;font-family:'Cambria','serif''></span></p>
                      
                      	<p style='margin:0in;margin-bottom:.0001pt'><span style='font-family:'Cambria','serif''>The
                      	first time you open Outlook after this e-mail implementation, you may
                      	experience a slight delay as the address book is updated with the new e-mail
                      	addresses.&nbsp; </span></p>
                      
                      	<p style='margin:0in;margin-bottom:.0001pt'><span style='font-family:'Cambria','serif''></span></p><br>
                      
                      	<p style='margin:0in;margin-bottom:.0001pt'><span style='font-family:'Cambria','serif''>If
                      	you have any questions, please contact the Help Desk at	1-800-555-5555.</span></p>" #<--- Not the closing doublequote.
                      #The message is now ready to be sent. Take the flags you have changed and use them as arguments.
                      #In this case, we want to specify the To, From, Subject, Body, BCC, and we want it to go as an HTML message.
                      
                      	Send-SMTPmail -to "$sTo" -from "$sFrom" -subject "$sTitle" -body "$sBody" -bcc $sbcc -html
                      }

Open in new window


Hopefully, this helps to demystify the process of sending an e-mail using PowerShell v1.0.
1
6,779 Views
GusGallowsSupport Escalation Engineer
CERTIFIED EXPERT

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.