Using Powershell’s new-webserviceproxy with Exchange Web Services

The other day I was working on a case where the customer was using VBScript and CDO 1.21 to make some changes in some mailboxes, and I couldn't help but feel that we were working in the past.  Don’t get me wrong, there’s a lot of tried and tested VBScript and CDO 1.21 code out there, but I found myself wondering what the “new” way to do this would be.

I started looking at using Powershell to automate a .Net HttpWebRequest to post to an EWS endpoint, and just build the SOAP requests myself (or leverage an XmlDocument), but while I was researching this I stumbled upon something slightly more interesting.

The version of Powershell that is included with the Windows 7 Beta includes a new cmdlet called new-webserviceproxy and it does exactly what it sounds like.  You can point it at a wsdl file, and it auto-generates a proxy in a way that seems very similar to the Visual Studio auto-generated proxies.

The following is the result of a good deal of trial and error, but what you end up with is a output that displays some basic information about all of the emails in your inbox.

<# Untested sample code, use at your own risk! #>

 

## Setup the Exchange Service Binding

$uri = "https://exchangeserver/ews/exchange.asmx"

$exchangeservicebinding = new-webserviceproxy -NameSpace "EWS" -URI $uri -UseDefaultCredential -Class EWS

$exchangeservicebinding.RequestServerVersionValue = new-object EWS.RequestServerVersion

$exchangeservicebinding.RequestServerVersionValue.Version = [EWS.ExchangeVersionType]::Exchange2007_SP1

$exchangeservicebinding.Url = $uri

 

## Create and Populate the Parent Folder ID Collection

[EWS.DistinguishedFolderIdType]$parentfolderid = new-object EWS.DistinguishedFolderIdType

$parentfolderid.Id = [EWS.DistinguishedFolderIdNameType]::inbox

[EWS.BaseFolderIdType[]]$parentfolderids = $parentfolderid

 

## Create an ItemShape and set it to return All Properties

[EWS.ItemResponseShapeType]$itemshape = new-object EWS.ItemResponseShapeType

$itemshape.BaseShape = [EWS.DefaultShapeNamesType]::AllProperties

 

## Create the FindItemType object and populate with the Parent Folder Ids and Item Shape

[EWS.FindItemType]$finditemtype = new-object EWS.FindItemType

$finditemtype.ParentFolderIds = $parentfolderids

$finditemtype.ItemShape = $itemshape

 

## Make the call to the webservice

[EWS.FindItemResponseType]$finditemresponses = $exchangeservicebinding.FindItem($finditemtype)

 

## Loop through the returned messages and print some basic info

[EWS.MessageType]$messagetype

foreach($messagetype in $finditemresponses.ResponseMessages.Items[0].RootFolder.Item.Items)

{

    Write-Host "From: " $messagetype.From.Item.Name

    Write-Host "Subject: " $messagetype.Subject

    Write-Host "Received: " $messagetype.DateTimeReceived.Date

    Write-Host "-------------------------------------------------------"

    Write-Host "ItemId: " $messagetype.ItemId.Id

    Write-Host "======================================================="

    Write-Host

}

<# download code here #>

The above code obviously has no error handling, but hopefully it shows a basic example of how this new cmdlet can be used.

If you want to dig in further, make use of the get-member cmdlet to examine objects of the types that are generated by the proxy, and you can also inspect the object using format-custom (alias fc) as follows (This can be done for any of the object types in the above code):

  1: $exchangeservicebinding | get-member
  2: $exchangeservicebinding | fc