Exchange Web Services (EWS)

Früher war MAPI/CDO der bevorzugte Weg, um an die Inhalte eines Exchange Servers (Postfach und öffentliche Ordner) zu kommen. Allerdings hat dieser Weg in der modernen Zeit diverse Einschränkungen. Als 16/32bit Applikation bzw. COM-DLL ist der Weg in die Zukunft nicht einfach. Zudem erfolgt die Kommunikation per RPC gegen den Postfachserver. HTTPS wäre aber viel besser. Mit Exchange 2000/2003 gab es einen Zwischenschritt, da über das Protokoll WebDAV ein Zugriff auf Inhalte per HTTPS möglich wurde. Besonders elegant war dies aber auch nicht und mit Exchange 2007 wurden erstmals die Webservices bereit gestellt, welche zukünftig alle anderen APIs (WebDAV, CDO, ExOLEDB und OWA Url Commmands) ersetzen sollen. Mit Exchange 2010 wurden dann eine ManagedAPI für .NET bereit gestellt, dass Entwickler sehr viel einfacher arbeiten können.

Funktionsumfang

Was sie mit Webservices heute schon abdecken können, zeigt ein Diagramm. Sie zeigt sehr gut, welche Funktionen schon in Exchange 2007 enthalten waren und dass Exchange 2007 SP1 den Exchange 2007 Funktionsumfang quasi komplettiert hat. Natürlich wurden die Webservices mit Exchange 2010 nochmal erweitert.


Quelle: TechEd UNC324 What's New in Exchange Web Services in Microsoft Exchange Server 2010, Autor Albert Kooiman

Das Ernsthaftigkeit zum Einsatz von Exchange Web Services von Microsoft ist klar und deutlich: Sehr viele Produkte und Programme setzen mittlerweile auf EWS auf z.B. Entourage für Mac Web Service Edition, die TransporterSuite, Project Server 2010 für Aufgaben und immer mehr andere Tools von Microsoft und Drittherstellern. Die eigenständige Seite Webservice liefert eine allgemeine Beschreibung.

Über die Exchange Web Services ist daher ein einfacher, internettauglicher, plattformunabhängiger Zugriff auf Inhalte möglich. Per Webservice kann sich ihr Programm sogar informieren lassen, wenn sich in einem Ordner etwas ändert. Allerdings funktioniert das nur Asynchron und nur pro Ordner. Es ist daher kein Ersatz für die Storesinks von Exchange 2000/2003. Allerdings kann man über die SynchronizationAPI Änderungen sehr einfach ermitteln und darauf reagieren.

Exchange Web Services nutzen

Ehe es von Microsoft die "Managed API" zu den Exchange WebServices gab, muss man sich noch selbst die WSDL-Datei besorgen und sich Proxy-Klassen schreiben und sehr genau prüfen, welche Parameter an welcher Stelle eingesetzt werden sollen. All Links zum Einsatz ohne Managed API habe ich mittlerweile an das Ende der Seite verschoben. (Siehe Exchange 2007 Webservices ohne Managed API). Sie sind immer noch wichtig, wenn Sie mit Programmen auf Exchange zugreifen wollen, die nicht .NET unterstützen, z.B. Java, Unix etc. Ansonsten würde ich speziell für Einsteiger stickt dazu raten, die Managed API zu nutzen.

Die sind aber erst mal herunter zu laden und auf dem Client zu installieren, damit Sie diese auch nutzen können.

MSDN: Exchange Web Services Managed API 1.2 SDK
http://msdn.microsoft.com/en-us/library/dd633710(v=EXCHG.80).aspx
Exchange Web Services Managed API 1.2 http://www.microsoft.com/download/en/details.aspx?id=28952

Exchange 2010 Service Pack 1 (SP1) Web Services Software Development Kit (SDK)
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=d55dcd05-1dd6-4f44-956f-82f052ee7d82

Exchange API-Spotting Exchange 2010 SDK March update
http://blogs.msdn.com/exchangedev/archive/2010/03/03/Thom-Randolph.aspx

Die Installation muss auf den System erfolgen, von dem aus der Zugriff auf die Daten erfolgen soll. Es ist nicht mehr erforderlich, eine Anwendung oder zusätzliche API auf dem Exchange Server zu installieren.

Nach Abschluss der Installation gibt es aber kein Icon im Startmenü o.ä. Sie können dann in ihrem Projekt einfach die neuen DLLs einbinden und dann basierend darauf eine neue Instanz eines Objekts zu erstellen und für Diagnosezwecke das Tracing zu aktivieren.

using Microsoft.Exchange.WebSerivces.Data;
using Microsoft.Exchange.WebSerivces.Autodiscover;

/* ewsserver initialisieren */
ExchangeService ewsservice= new ExchangeService;
/* ewsserver initialisieren wenn Ziel Exchange 2007 ist*/
ExchangeService ewsservice= new ExchangeService(Exchange2007_SP1);

/* Optional Credentials angeben */
ewsservice.Credentials = new NetworkCredential("name", "pwd", "domain");

/*  bei Bedarf ein trace einschalten */
ewsservice.traceEnabled = true;

/*  URL definieren ODER per Autodiscover ermitteln */
service.Url = new Uri("https://servername/EWS/Exchange.asmx");
service.AutodiscoverUrl("mailadresse@domain.tld");

EWS-Filter: Zugriff kontrollieren ab Exchange 2010 SP1

Damit nicht jeder Client nun mit einem bekannten Benutzernamen per EWS und frei verfügbaren Tools im Store tummelt, kann ein Administrator seit Exchange 2010 SP1 auch hier mehr Einstellungen vornehmen. Dazu sind die beiden folgenden Commandlets relevant. Das SP1 für Exchange 2010 hat zwei Befehle erweitert:

Beide Commandlets kennen seit SP1 die folgenden Parameter:

Die Felder müssen nicht mit "Wahr" oder "Falsch" gefüllt sein, sondern können auch "leer" sein. Nach meiner Erfahrung überstimmten "pro Benutzer" eingestellte Parameter die organisationsweiten Einstellungen. Wenn nichts eingestellt ist, dann ist alles "erlaubt". (Das konnte ich aber z.B. mangels Mac noch nicht testen.

Powershell und EWS

Aus VBScript ist es nicht möglich, Managed-Code einfach aufzurufen. Aber Powershell erlaubt dies schon sehr einfach. die folgenden Zeilen bauen eine Verbindung zum Exchange Server per EWS auf.

# Laden der Manages API-DLLs in den Prozessraum

[void][Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\1.0\Microsoft.Exchange.WebServices.dll")


# ews-Klasse instanzieren
# Wenn Sie auf Exchange 2007 zugreifen, müssen Sie dies mit angeben

$ews = new-object Microsoft.Exchange.WebServices.Data.ExchangeService
#$ews = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)


# Dann müssen Sie die EWS-Url angeben oder per Autodicsover anhand der Mailadresse ermitteln lassen.

# Ermitteln mit Mailadresse
$ews.AutodiscoverUrl($mailbox)

# alternativ: Aktuellen User verwenden
#$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
#$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
#[adsi]$aceuser = [ADSI]$sidbind
#$ews.AutodiscoverUrl($aceuser.mail.ToString())

# Alternativ URL fest vorgeben
$ews.Url = [system.URI]"https://casserver/ews/exchange.asmx"


# Optional mit anderen Benutzerdaten anmelden
$ews.Credentials = New-Object System.Net.NetworkCredential("username","passwort","domain")

Danach steht die Klasse für die weitere Verwendung zur Verfügung.

Mail per EWS versenden

Sicher kann ich auch per SMTP eine Mail einfach versenden. Das geht per Blat oder auch über Mail per CDO Senden, aber dazu ist immer SMTP und Port 25 erforderlich. Viele Firewalls, Virenscanner etc. blocken dies und und per HTTP und EWS ist man hier zum einen flexibler und die Mail landen auch noch in "gesendete Objekte".

Sie benötigen noch die Initialisierungsschritte der vorigen Abschnitts und dann reichen folgende wenige Zeilen:

[Microsoft.Exchange.WebServices.Data.EmailMessage]$message = `
    New-Object Microsoft.Exchange.WebServices.Data.EmailMessage($ews);
$message.Subject = "Betreff";
$message.Body = "Testmessage.";
$message.ToRecipients.Add("user@domain.tld");
$message.SendAndSaveCopy();

Natürlich können Sie der Mail noch Anlagen, Formatvorlagen etc. verpassen

Posteingang per EWS auslesen

Auch das Abrufen von Mails aus dem Posteingang und anderen Ordnern ist mit der Managed API sehr einfach geworden. Auch hier benötigen Sie den Initialisierungsteil und dann geht es sehr einfach weiter. Ungewohnt ist hier, dass man neben dem Ordner sich erst mal einen "View" definieren muss, damit man die gewünschten Daten bekommt. Das ist aber ganz hilfreich, denn wenn Sie wissen, nach was sie suchen, dann brauchen Sie nicht alle Inhalte anzufordern und auf dem Client zu filtern, sondern den Server kann schon filtern.

Write-Host "Bindung Inbox"
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($ews, `
       [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
write-host "Number or Unread Messages : " + $inbox.UnreadCount
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)
$findResults = $ews.FindItems([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$view)
""
"Last Mail From : " + $findResults.Items[0].From.Name
"Subject : " + $findResults.Items[0].Subject
"Sent : " + $findResults.Items[0].DateTimeSent

Diese Zeilen zeigt die erste Mail an.

Kalenderzugriff per EWS

Per EWS ist auch ein Zugriff auf Termine möglich. Hier ein paar Links zu weiterführenden Seiten:

Autodiscover und Umleitung

Ehe Outlook 2007 SP1 auch mit SRV-Records arbeiten konnte, konnte ein Admin also nur ein Zertifikat für "autodiscover.maildomain.tld" konfigurieren oder ohne SSL einen HTTP-Redirect machen. Das funktioniert mit Outlook 2007 schon sehr gut aber wer per Exchange Web Services darauf zugreifen will, muss eine "Callback"-Funktion einrichten, die die Rückfrage bezüglich der "Umleitung" behandelt.

Das geht mit Powershell 1.0 schon gar nicht und mit 2.0 ist die Komplexität für die MSXFAQ eher hoch. Sie sollten dann einfach die URL manuell angeben.

$ewsservice.url = "https://exchangeserver/EWS/exchange.asmx

Exchange 2007 "Impersonation" über "ms-Exch-EPI-May-Impersonate"

Achtung
Diese Einstellungen gelten nur für Exchange 2007. Bei Exchange 2010/2013 wird Impersonation über eine RBAC-Rolle gesteuert. Siehe nächstes Kapitel.

Oft reicht es nicht per EWS einfach sein eigenes Postfach zu öffnen. So wird es immer Dienstkonten geben, die in Postfächer anderer Benutzer zugreifen müssen. Dazu gibt es wie bei MAPI ebenfalls drei Optionen:

Der letzte Fall ist das Thema dieses Abschnitts. Da der erste CAS-Server schon die Anmeldung übernimmt und die Server untereinander "vertrauenswürdig" sind, ist damit ein Durchgriff auf alle Postfächer auch in anderen Standorten (CAS zu CAS Proxy) möglich. Damit kann ich einem Konto das Recht geben, quasi als der angegebene Benutzer zu arbeiten, ohne sich explizit mit dessen Anmeldedaten zu authentifizieren. Dazu unterscheidet Exchange zwei fast gleichlautende Berechtigungen:

Diese beiden Berechtigungen sind also unabhängig von den üblichen "Vollzugriffs-Rechten" auf Postfächer zu sehen, wie diese auf Mailboxrechte beschrieben werden. Impersonation greift nur beim Zugriff über Webservices während die normalen Postfachrechte für den Zugriff über OWA, MAPI, CDO etc. erforderlich sind.

„The calling account cannot be a member of any administrator group.
This permission is explicitly denied to those groups“

Quelle: Configuring Exchange Impersonation (Exchange Web Services) http://msdn.microsoft.com/en-us/library/exchange/bb204095(v=exchg.80).aspx

Die Einrichtung dieser Berechtigungen ist nur über die Powershell möglich. Hier am Beispiel eines CAS-Server.

Add-ADPermission `
  -Identity CAS1 `
  -User SVCUser`
  -extendedRights ms-Exch-EPI-Impersonation

Oder hier über eine Schleife, um alle CAS-Server auf einmal zu konfigurieren:

Get-ExchangeServer | where {$_.IsClientAccessServer -eq $TRUE} | ForEach-Object {Add-ADPermission -Identity $_.distinguishedname -User (Get-User -Identity SVCUser | select-object).identity -extendedRights ms-Exch-EPI-Impersonation}

Die Berechtigungen auf die Postfachdatenbank ist über folgenden Befehl möglich:

Add-ADPermission `
  -Identity SG1/MBDATABASE1 `
  -User SVCUser`
  --ExtendedRights ms-Exch-EPI-May-Impersonate

Oder auch hier wieder für den Zugriff auf alle Postfächer aller Datenbanken:

Get-MailboxDatabase | ForEach-Object {Add-ADPermission -Identity $_.DistinguishedName -User SVCUser -ExtendedRights ms-Exch-EPI-May-Impersonate}

Der Benutzer muss also auf dem CAS-Server das Recht bekommen, überhaupt Impersonation anfordern zu können und auf der Postfachdatenbank die Erlaubnis, mit Impersonation auf die Daten darin zuzugreifen. Das Konto darf zudem kein Administrator sein, da über die Gruppe der Administratoren auch hier wieder ein "DENY" dieses Rechte unterbinden würde.

Wenn die Vergabe von Berechtigungen auf der Datenbank zu weit gehen, kann natürlich ebenfalls über die Benutzer die Berechtigungen vergeben:

Add-ADPermission `
  -Identity "Mailbox"`
  -User SVCUser `
  -extendedRight ms-Exch-EPI-May-Impersonate

Hiermit kann dann das Dienstkonto auf das Postfach zugreifen.

Diese Funktion wird z.B. auch bei der Transporter Suite eingesetzt, damit diese alle Nachrichten in die Exchange Postfächer übertragen kann.

Wenn Sie nun über EWS diese Funktion nutzen wollen, dann müssen Sie natürlich den Web Services über Impersonation konfigurieren. hier ein Auszug:

ewsservice.impersonatedUserID = new impersonatedUserID(ConnectingIDType.SID,wert)
ewsservice.impersonatedUserID = new impersonatedUserID(ConnectingIDType.PrincipalName,wert)
ewsservice.impersonatedUserID = new impersonatedUserID(ConnectingIDType.SmtpAddress,wert)

Bei Exchange 2010 müssen Sie hier aber dem User auch die Rechte geben (RBAC)

Exchange 2010/2013: EWS Impersonation

Mit Exchange 2010 wurde die Steuerung der Berechtigung über "RBAC" geregelt, so dass eine direkte Vergabe von Rechten an die CAS-Server entfällt. Damit ein Account oder eine Gruppe das Recht "Impersonate" hat, wird eine ManagemenRolle zugewiesen mit:

New-ManagementRoleAssignment `
    -Name:impersonationAssignmentName `
    -Role:ApplicationImpersonation `
    -User:serviceAccount

Oder bei Zuweisung an eine Gruppe über

New-ManagementRoleAssignment `
    -Name:impersonationAssignmentName `
    -Role:ApplicationImpersonation `
    -Securitygroup:Gruppenname

EWS für OOF

Hierzu hat Mike Pfeiffer einen netten Artikel samt Skript geposted

EWS und Elementgrößen

Haben sie schon mal versucht, ein Postfach von Notes oder Exchange nach Exchange 2007/2010 zu verschieben, in dem eine Mail > 50 MB lag?. Richtig, das geht nicht, das die Migration über EWS erfolgt. Microsoft hat hier aber einen "Schutz" gegen angriffe eingebaut der ein Upload von größeren Elementen verhindert. Wäre doch Schade, wenn ein böser Prozess einen Upload von 20 GB "starten" (aber eh nie abschließen) würde und Exchange dafür Platz/RAM reservieren müsste. Daher gibt es ein Limit, welches Sie aber hochsetzen können.

Das "Problem" betrifft nicht nur Migrationen sondern jede Art von Zugriff auf EWS.

Ein Attachment "vergrößert" sich beim Einsatz von EWS
20 MB: Dateigröße auf Disk
30 MB Datei nach MIME-Konvertierung (+33%)
43 MB Datei codiert innerhalb der XML/SOAP-Message (+36%)
Die individuellen Größen können abweichen.

Entsprechend können Sie mehrere Stellen "treffen", bei denen der IIS übergrenzen steuern. Letztlich sind es Änderungen an der "web.config".

<configuration>
	<system.web>
		<httpRuntime maxRequestLength="10240" />
	<system.web>
<configuration>

Der Wert wird in "Kilobyte" angegeben.

Achtung
Dies ist eine XML-Datei und Tippfehler bewirken, dass der entsprechende Applicationpool nicht mehr startet. Sie können viele Einstellungen auch im IIS-Manager machen.

Danach ist der IIS mit einem IISRESET durchzustarten, damit die Einstellungen aktiv werden.

Hier eine unvollständige Liste der Parameter, mit denen ich schon mal konfrontiert worden bin.

Parameter   IIS 2007 2010
maxRequestLength web.config 4KB 13280KB 2097151KB
MaxReceiveMessageSize web.config na ? na ? RTM: 13600000
SP1: 35000000
Achtung: 8x vorhanden
maxAllowedContentLength web.config 30 MB 30 MB 35 MB
executionTimeout web.config 110 Sek    

Es gibt noch weitere Grenzwerte (z.B. connectionTimeout), die aber nur bei sehr großen Anlagen über sehr langsame Leitungen zum Tragen kommen. Auch Funktionen wie "Connection Filterung" oder eine vorgelagerte Firewall können natürlich eigene Grenzen umsetzen und am Ende

EWS und Notification Services

Die Webservices öffnen noch einen netten Weg: eine Anwendung kann per Webservices eine "Pushbenachrichtigung" einstellen, d.h. der Exchange Server informiert die Anwendung darüber, wenn sich in einem Postfach z.B. etwas tut. Dazu muss die Anwendung selbst auch einen Webservice bereitstellen, welcher von Exchange dann "rückwärts" aufgerufen wird. Als Programmierer weise ich also Exchange an, von von meiner Anwendung angebotenen Webservice bei bestimmten Situationen aufzurufen. Suchen Sie nach

SubscribePullNotification

Sie müssen aber einen Listener entwickeln, welcher dann von Exchange aufgerufen (ebenfalls WebService) wird. Details finden Sie auch hier:

Wenn Sie alles richtig gemacht haben aber ihr Webservice dennoch nicht angesprochen wird, dann sollten Sie einen Blick ins Eventlog tun:.

Event Type:      Warning
Event Source:    MSExchange Web Services
Event Category:  Core
Event ID:        6
Description:
Unable to send a notification for subscription 
fsdfllkn4325kjbzuvjdj2sj1jshj2dk2kj3s1fefh13g4g4sjg34as3244=. (Send attempts: 3)
Event Type:      Error
Event Source:    MSExchange Web Services
Event Category:  Core
Event ID:        7
Description:
After 8 unsuccessful attempts to send a notification for subscription 
fsdfllkn4325kjbzuvjdj2sj1jshj2dk2kj3s1fefh13g4g4sjg34as3244=
K8=, subscription has been removed.
Event Type:      Warning
Event Source:    MSExchange Web Services
Event Category:  Core
Event ID:        5
Description:
Unable to send a notification for subscription 
fsdfllkn4325kjbzuvjdj2sj1jshj2dk2kj3s1fefh13g4g4sjg34as3244=
K8=. Will retry.

Die lange Zeichenkette ist in Realität eine Base64-codierte Binärdatei, die man zwar decodieren kann, aber viel mehr als den Servername und ein paar kryptische Zeichen sieht man nicht. Es ist aber zumindest ein Hinweis, wohin der Sink gehen sollte. Die Einträge sind übrigens auf dem CAS-Server hinterlegt und wenn ich den Entwicklern glauben darf gibt es keine einfache Möglichkeit eine Liste der aktiven Benachrichtigungen zu generieren.

Man kann allerdings die IIS-Logs durchsuchen, wer, wann ein "Subscribe" auf den Exchange Web Services macht, d.h. im IISLog einfach mal nach "ews/exchange.asmx?SoapAction=Subscribe" suchen.

https://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=931885&SiteID=17
For push notifications, you need to write your own web service that implements the NotificationService.wsdl interface. Then you subscribe to receive notifications using the EWS Subscribe web method with a PushSubscriptionRequest sub-element. You will notice that the PushSubscriptionRequestType surfaces a status frequency (how often you want to be alerted of changes) and a URL which is the URL of YOUR web service. Then EWS will call the SendNotification web method on your service with the changes. You can unsubscribe by responding to the SendNotification web method with a subscription status of "Unsubscribe".

EWS Performance Analysen über das IISLog

Sie wissen ja nun, dass die Web Services ein Teil des Webservers IIS sind. Damit landen im IISLog auch die entsprechenden Anfragen. Hier drei exemplarisch Zeile, die zur Lesbarkeit gekürzt sind.

POST /ews/Exchange.asmx - - 401 2
POST /ews/Exchange.asmx - Domain\User 500 0
POST /ews/Exchange.asmx SoapAction=FindItem;Version=0;RpcC=27;RpcL=137;LdapC=10;LdapL=58; Domain\User - 200 0

Die erste Zeile zeigt eine anonyme Anfrage, die vom Server natürlich mit einem 401.2 Fehler quittiert werden. Die zweite Zeile hingegen zeigt, dass da wohl keine gültige Abfrage aber mit gültigem Benutzer erfolgt und mit einem 500er beantwortet wird. Hier wäre ein NETMON-Mitschnitt denkbar, um den XML-Request und die Details der Antwort zu sehen.

Besonders interessant ist die Zeile einer erfolgreichen EWS-Anfragen. Hier ist nicht nur der Befehl "FindItem" sichtbar, sondern auch ein paar Werte zur internen Verarbeitung. Bislang habe ich noch keine Bestätigung aber die Zahlen dürften die Millisekunden sein, die in der entsprechenden Routine verweilt wird.

Leider gibt es keinen Parser, der diese Details genauer auswertet.

Exchange 2010 EWS Throttling

Neu in Exchange 2010 ist die Funktion, dass ein Client nicht den Server per Web Services voll machen. Wer also zu "verfressen" mit EWS arbeitet, wird ausgebremst. Sinnvoll ist dies bei der Entwicklung des Code zu berücksichtigen und "Paged Searches" zu verwenden. Weitere Infos finden Sie u.a. auf:

Exchange 2007 Webservices ohne Managed API

Eine Echtzeitverarbeitung mit der Option, eine Änderung des Clients zu verhindern oder synchron andere Funktionen durchzuführen ist mit Webservices scheinbar nicht möglich.

Hier nur eine kleine Auswahl von Links. Die MSDN-Seite ist sicher die beste Quelle.

EWS.DLL als Proxyklasse

Normalerweise nutzt ein Entwickler WSDL, um von einem Webservice die unterstützten Schnittstellen zu erfahren. Dazu muss man aber zur Entwicklungszeit natürlich zugriff auf den Webservice haben. Und nicht alle Entwicklungsumgebungen unterstützen direkt die Einbindung der WSDL-Informationen. Man kann daher die Beschreibung in einer DLL "einpacken", so dass auch andere Umgebungen eine elegante Unterstützung bei der Entwicklung erlauben.

Eleganter weise hat Glen Scales schon wieder die Arbeit getan, die Microsoft im BLOG nicht getan hat und stellt eine EWS.DLL direkt bereit

EWS.DLL zum Download
http://msgdev.mvps.org/exdevblog/ewsutil.zip.

Mit dieser EWS ist es dann auch in Powershell seht einfach auf Exchange 2007 Ressourcen zuzugreifen. Hier ein Beispiel, um sich per Powershell auf den Posteingang zu verbinden.

[void][Reflection.Assembly]::LoadFile("C:\Programme\msxfaq\EWSUtil.dll")

$mbMailboxEmail = "admin@msxfaq.local"
$ewc = new-object EWSUtil.EWSConnection($mbMailboxEmail,$false,$null,$null,$null,$null)

$dTypeFld = new-object EWSUtil.EWS.DistinguishedFolderIdType
$dTypeFld.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::inbox

$mbMailbox = new-object EWSUtil.EWS.EmailAddressType
$mbMailbox.EmailAddress = $mbMailboxEmail
$dTypeFld.Mailbox = $mbMailbox

$fldarry = new-object EWSUtil.EWS.BaseFolderIdType[] 1
$fldarry[0] = $dTypeFld
$msgList = $ewc.FindUnread($fldarry, $null, $null, "")
if ($msgList.Count -ne 0){
    "Inbox:" + $msgList[0].Subject.ToString()
}

Sie können daher die Beschreibung in eine DLL "einpacken", so dass auch andere Umgebungen eine elegante Unterstützung bei der Entwicklung erlauben.

Visual Studio und Webservices

Natürlich können Visual Studio 2005 und 2008 ganz einfach Webservices einbinden. Über das Projektmenü" wird ein Assistent zum einbinden eines Webservice gestartet, der dann eine "Hilfsklasse" erstellt, die in der späteren Entwicklung einfach genutzt werden kann.

VS 2005 Webservice Assistent

Mit Visual Studio 2008 gibt es eine "Service Referenz"

VS2008 Service reference

Danach können Sie in Visual Studio die Webservices wie jede andere Klasse verwenden

EWS und Limits

Per Default erlauben die Exchange 2007 Webservices nur Anlagen bis 10 Megabyte. Dies ist ein Schutz gegen übergroße http-Requests und sollte für die Migration temporär erhöht werden.

Dazu ist auf dem CAS-Server die WEB.CONFIG im virtuellen Verzeichnis „EWS“ der Default Webseite anzupassen. Diese liegt normalerweise auf C:\Program Files\Microsoft\Exchange Server\ClientAccess\exchweb\ews). Suchen Sie in der Datei nach dem Tag: <system.web> in dem sich folgende Zeile befindet:

<httpRuntime maxRequestLength="10240" />

Tragen Sie hier die gewünschte maximale Größe ein. Denken Sie aber daran, nach der Migration den Wert wieder auf eine für ihr Unternehmen passende Größe einzustellen. ACHTUNG: Dieser Wert ist nach einem Update (Servicepack, Rollup) zu prüfen und eventuell erneut zu setzen.

Zudem sollten Sie im IIS noch die Konfiguration anpassen:

C:> cd \Windows\System32\inetsrv
C:> appcmd set config "Default Web Site/ews" -section:requestFiltering -requestLimits.maxAllowedContentLength:[size in Bytes!]
C:> iisreset

Danach sollten die neuen Grenzen gelten.

EWS und Memory

Bei Verschiedenen Programmen habe ich gesehen, dass diese immer auf dem Exchange Server immer mehr Speicher fressen und dann EWS die Schuld gegen wird. Genau genommen ist es aber eine unsaubere Programmierung des Clients. Exchange "cached" Daten. Der Prozess der "Garbage Collection" kann nur solche Speicherbereiche wieder freigeben, wenn die darin vorgehaltenen Objekte als "nicht mehr erforderlich" gekennzeichnet sind. Dazu gibt es extra die "Finalize"-Methode:

Wenn Sie als Entwickler also in einen Programm z.B. die EWS-Instanz nicht wieder frei geben, sondern einfach weiter neue Instanzen öffnen, dann wird der belegte Speicher nicht frei gegeben. Zugegeben, ich bin selten in der Situation mir darüber Gedanken machen zu müssen, da meine Skripte eigentlich nicht "endlos" laufen, sondern am Ende terminieren und damit den Speicher frei geben. Das ist aber anders, wenn Sie eine permanent aktive Lösung entwickeln.

EWS Synchronisation

Je weniger Server mit Exchange 2003 und früher arbeiten, desto eher gibt es Exchange 2007 und höher, die alle EWS anbieten und auch die Microsoft Cloud und andere Anbieter bieten EWS als einziger Weg auf die Postfächer an. MAPI und CDO sind auf dem absteigenden Asts.

Da könnte man ja auf die Idee kommen, einfach per EWS z.B. zwei Postfächer in unterschiedlichen Exchange Organisationen "Synchron" zu halten, z.B. um eine elegante Koexistenz zu erreichen oder auch eine Stichtagsmigration vorzubereiten.

Aktuell habe ich selbst noch kein "fertiges Skript" oder gar eine Lösung dazu. Sie können mir aber gerne Links und Erfahrungen mitteilen, die ich hier gerne ergänze.

Weitere Links

Hier nur eine kleine Auswahl von Links. Die MSDN-Seite ist sicher die beste Quelle.

Tags:Webservice Code Programmieren