Microsoft Exchange Server PowerShell Cookbook(Third Edition)
上QQ阅读APP看书,第一时间看更新

Sending SMTP e-mails through PowerShell

As an Exchange administrator, you will probably need an automated solution to send e-mails from your PowerShell scripts. Whether it's used to send notifications to users in a specific database or e-mail the output of your scripts to a reporting mailbox, the transmission of messages such as these will prove very useful while performing common day-to-day administrative scripting tasks. In this recipe, we'll take a look at how you can send SMTP e-mail messages from PowerShell to the recipients in your Exchange organization.

How to do it...

PowerShell v2 and later includes a core cmdlet that can be used to send e-mail messages via SMTP to one or more recipients. Use the following syntax to send an e-mail message:

Send-MailMessage -To user1@contoso.com `
-From administrator@contoso.com `
-Subject "Test E-mail" `
-Body "This is just a test" `
-SmtpServer ex01.contoso.com

How it works...

In PowerShell v1, the Send-MailMessage cmdlet didn't exist. In the early days before Exchange 2007 SP2 and PowerShell v2 support, we had to use the classes in the System.Net.Mail namespace in the .NET Framework to send SMTP e-mail messages. This was difficult for some administrators because working with .NET classes can be confusing without prior programming experience. The good news is that the Send-MailMessage cmdlet utilizes the same .NET classes that allow you to create rich e-mail messages that can contain one or more attachments, using an HTML formatted message body, support message priority, and many more. Here are some of the most useful parameters that can be used with the Send-MailMessage cmdlet:

  • Attachments: This specifies the path to the file that should be attached. It separates multiple attachments with a comma.
  • Bcc: This allows you to specify a blind copy recipient. It separates multiple recipients using a comma.
  • Body: This specifies the content of a message.
  • BodyAsHtml: This is a switch parameter that ensures that the message will use an HTML-formatted message body.
  • Cc: This allows you to specify a carbon copy recipient. It separates multiple recipients using a comma.
  • Credential: You can provide a PSCredential object created by the Get-Credential cmdlet to send the message using the credentials of another user.
  • DeliveryNotificationOption: This specifies the delivery notification options for the message. The default value is None, but other valid options are OnSuccess, OnFailure, Delay, and Never.
  • Encoding: This specifies the encoding of the e-mail, such as an S/MIME and non-MIME character set.
  • From: This is the e-mail address of the sender. You can define a display name using the Dave <dave@contoso.com> format.
  • Priority: This specifies the importance of the message. The default value is Normal. The remaining valid values are High and Low.
  • SmtpServer: This needs to be the name or IP address of your SMTP server. When working in an Exchange environment, this will be set to one of your Hub Transport servers.
  • Subject: This is the subject of the e-mail message.
  • To: This allows you to specify an e-mail recipient. It separates multiple recipients with a comma.

There's more...

When using this cmdlet, you need to specify an SMTP server in order to submit the message. Unless you are already using some type of mail relay system within your environment, you'll want to use a Mailbox server in your Exchange organization. Out of the box, Exchange servers will not allow workstations or untrusted servers to relay e-mail messages. Depending on where you are sending the message from, you may need to allow the machine running your scripts to relay e-mails.

PowerShell v2 and later includes a preference variable called $PSEmailServer that can be assigned the name or IP address of an SMTP server. When this variable is defined, you can omit the -SmtpServer parameter when using the Send-MailMessage cmdlet. You can add this variable assignment to your PowerShell profile, so that the setting will persist across all of your shell sessions.

Sending messages with attachments

You may want to write a script that generates a report to a text or CSV file, and then e-mail that data to an administrator mailbox. The –Attachment parameter can be used with the Send-MailMessage cmdlet to do this. For example, let's say that you've generated a CSV report file for the top 10 largest mailboxes in your environment and this needs to be e-mailed to your staff. The following command syntax could be used in this scenario:

Send-MailMessage -To support@contoso.com `
-From powershell@contoso.com `
-Subject "Mailbox Report for $((Get-Date).ToShortDateString())" `
-Body "Please review the attached mailbox report." `
-Attachments c:\report.csv `
-SmtpServer ex01.contoso.com

Notice that all we need to do here is provide the path and filename to the -Attachment parameter. You can send multiple message attachments this way by providing a comma-separated list of files.

Sending command output in the body of a message

Instead of exporting command data to an external file and sending it as an attachment, you may want to add this information to the body of an e-mail. In this example, we'll send a message that displays the top 10 largest mailboxes in the organization in the body of an HTML-formatted message:

[string]$report = Get-MailboxDatabase | 
Get-MailboxStatistics| ?{(!$_.DisconnectDate) -and `
($_.DisplayName -notlike "HealthMailbox*")} | 
Sort-Object TotalItemSize -Desc | 
Select-Object DisplayName,Database,TotalItemSize -First 10 | 
ConvertTo-Html
Send-MailMessage -To support@contoso.com `
-From powershell@contoso.com `
-Subject "Mailbox Report for $((Get-Date).ToShortDateString())" `
-Body $report `
-BodyAsHtml `
-SmtpServer ex01.contoso.com

Here, you can see that the report data is generated with a fairly sophisticated one-liner, and the output is saved in a string variable called $report. We need to strongly type the $report variable as a string because that is the data type required by the -Body parameter of the Send-MailMessage cmdlet. Notice that we're using the ConvertTo-Html cmdlet at the end of the one-liner to convert the objects to an HTML document. Since the $report variable will simply contain raw HTML, we can assign this value to the –Body parameter, and use the -BodyAsHtml switch parameter to send the report data in the body of an HTML-formatted message.

See also

  • Allowing application servers to relay mail in Chapter 8, Managing Transport Servers
  • Sending e-mail messages with EWS in Chapter 12, Scripting with the Exchange Web Services Managed API
  • Reporting on the mailbox size in Chapter 4, Managing Mailboxes