Thursday, January 17, 2013

Sending Email from Office365 (Exchange Online) using PowerShell

Being a general purpose programmer I get to work on various projects using a variety of programming languages and technologies.

However, I never used PowerShell before. So when IT requested that I update one of their PowerShell scripts I was excited about the opportunity to use a language I've never touched before.

The task involved taking a HyperV backup script which got input from the user during run-time (what to backup, where to run to, etc) and:
  1. Making it run for all servers automatically.
  2. Send an e-mail report at the end.

The first step was quick and easy. The backup code was moved into a function which received the previous user-inputted data as parameters. The data was set at the beginning of the script and the servers list is an array that can be easily changed. (The IT requested it would be in the script itself and not an external file).

The second step tough, proved a lot more complicated.
If you have any knowledge of PowerShell you probably know the Send-MailMessage method which is used to send e-mails. The problem is that the company recently switched to Office365 (Exchange Online) and the Sned-MailMessage couldn't handle it.
After trying various methods the following code worked for me (it requires EWS to be installed, see below):


Add-Type -Path 'C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll'



$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2010_SP1



$service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList  user@email.com, "password"



$service.AutodiscoverUrl('user@email.com', {$true})



$message = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service

$message.Subject = 'subject text'

$message.Body = 'body text'

$message.ToRecipients.Add('target@email.com') 
$message.SendAndSaveCopy()


The code was based on a this guide so if you want detailed explenation you can go there, but basically it connects to your Office365 account with your credentials and sends the email from there, server side. It also saves a copy in your Sent items folder. If you don't want to save a copy just use Send() instead of SendAndSaveCopy().

The most notable changes were removing all the code that wasn't necessary for me (the code in the guide is very generic) and updating the  version of Add-Type I used (from 1.1 to 2.0).


In addition, this code requires Microsoft Exchange Web Services Managed API (version 1.1 or higher) to be installed.

2 comments:

  1. Excellent Work - Saved me hours of research and trial and error testing
    But I needed to add an attachment so added the following line

    $message.Attachments.AddFileAttachment("Status.txt")

    ReplyDelete