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
foreach($messagetype in $finditemresponses.ResponseMessages.Items.RootFolder.Item.Items)
Write-Host "From: " $messagetype.From.Item.Name
Write-Host "Subject: " $messagetype.Subject
Write-Host "Received: " $messagetype.DateTimeReceived.Date
Write-Host "ItemId: " $messagetype.ItemId.Id
<# 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