Test-EWS
Die Exchange Web Services (Siehe EWS) sind quasi der Nachfolger der früheren MAPI/CDO-Schnittstelle, die aber anstelle von RPC/TCP auf HTTP bzw. besser auf HTTPS aufsetzen. Damit sind sie "Cloud" und "Internet-Tauglich". Nun bietet jeder Exchange 2007 (oder neuer) Server die EWS-Schnittstelle an, aber nicht immer kann ein Administrator sicher sein, dass Sie korrekt funktioniert oder über den Reverse Proxy korrekt veröffentlicht wird. Daher habe ich mit mir Test-EWS ein PowerShell-Beispiel geschrieben, mit dem ich die meisten Fälle einfach testen kann.
Download und Einsatz
Um ihre eigene Umgebung mit ein paar EWS-Anfragen zu testen, können sie das folgende PowerShell-Script herunterladen und auf ihre Anforderungen anpassen. Sie werden es aber anpassen müssen. Insbesondere wenn z.B. Autodiscover nicht korrekt implementiert ist und Sie dann besser die URL für die Webservices angeben.
Umgekehrt ist aber genau das auch das Ziel dieses Scripts: Man kann verschiedene Dinge manuell vorgeben um zu sehen, welche Teilkomponente ein Problem hat und über die optionale "Trace"-Funktion sind Fehler sehr schnell auszumachen.
Das Skript trägt absichtlich die Version 1.0, da es wirklich der erste Wurf ist. Es half mir bislang bei Problemen mit einen Kunden und ist nie für den Dauereinsatz oder mehr gedacht gewesen. Es fehlen also alle Funktionen der Fehlerbehandlung, Logging etc. Es ist ein Test-Skript. Entsprechend finden Sie auch einige auskommentierte Zeilen, die ich als Vorlage im Skript belassen habe, um nicht immer danach suchen zu müssen.
Das Basisskript verbindet sich einfach mit dem angegebenen Postfach und zeigt die Anzahl der ungelesenen Mails im Posteingang.
Aufruf und Parameter
Für die Ausführung des Skripts reicht eine normale PowerShell als normaler Benutzer. Es ist weder die Exchange PowerShell noch eine privilegiert (Als Admin) gestartete PowerShell. Allerdings müssen Sie auf dem System die Exchange Web Services installiert haben. Ggfls. gibt es schon neuere Versionen.
Microsoft Exchange Web Services Managed API
Version 2.2.
https://www.microsoft.com/en-us/download/details.aspx?id=42951
Version 2.1:
http://www.microsoft.com/en-us/download/details.aspx?id=42022
Aktuell wird die
Entwicklung auf GitHub weiter geführt und auf
Nuget bereitgestellt
https://GitHub.com/officedev/ews-managed-api
https://www.nuget.org/packages/Microsoft.Exchange.WebServices/
Im Kopf des Skripts sind die Parameter aufgeführt:
param( [string]$MailboxSMTP = "User@msxfaq.local", [string]$Username = "", [string]$Domain = "", [string]$Password = "", [string]$ServiceURL = "", [switch]$useImpersonation, [string]$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll", [switch]$EWSTrace, [switch]$Verbose )
Die Bedeutung erschließt sich schnell:
Parameter | Bedeutung |
---|---|
MailboxSMTP |
Das ist die SMTP-Adresse des Postfachs, welches per EWS geöffnet werden soll. Achten Sie darauf, das Sie hier die "Primäre SMTP-Adresse" verwenden. Sekundäre SMTP-Adressen funktionieren nicht zuverlässig |
Username |
Optional können Sie hier einen Benutzernamen hinterlegen. Wird kein Benutzer angegeben, nutzt das Skript den aktuell angemeldeten Anwender |
Domain |
Wenn Sie beim Feld "Benutzername" keinen UPN eingebend, dann sollten Sie hier die Domäne spezifizieren. |
Password |
Wenn Sie einen Benutzernamen angeben, sollten Sie auch ein Kennwort hinterlegen. Wer Kennworte nicht im Klartext abspeichern will, kann Sie z.B. mit einem "(read-host -Prompt "Password für $Domain\$Username")" einlesen oder verschlüsselt speichern. Siehe PS Passworte |
ServiceURL |
Das Skript versucht eine automatische Erkennung mittels "Autodiscover". Wenn dies nicht funktioniert, können Sie hier eine Exchange EWS-URL manuell angeben, z.B. [string]$ServiceURL = "https://exchange.msxfaq.local/EWS/Exchange.asmx", |
dllpath |
Dieser Parameter gibt den Pfad zur erforderlichen WebService DLL an, die sie auf dem Computer installiert haben müssen. z.B. "C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll" "C:\Program Files\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll" Den Pfad müssen Sie ggfls. an die bei ihnen installierte Version anpassen. |
useImpersonation |
Setzen Sie diesen Parameter auf "$true", wenn Sie über EWS Impersonation mit dem angegebenen Benutzernamen auf das in "MailboxSMTP" angegebene Postfach per Impersonation zugreifen wollen. |
EWSTrace |
Wenn dieser Schaler aktiviert ist, liefert das Skript im Fehlerfall sehr ausführliche Informationen des Exchange Server sichtbar zurück. |
Verbose |
Dieser Schalter wird 1:1 an die aufgerufenen Commandlets weiter gegeben und das Skript selbst gibt einen Fortschritt mittels "Write-Verbose" aus. |
Die Komplexität der Parameter ist also überschaubar.
Beispiel mit Tracing
Hier ein Beispielabruf eines Postfachs mit expliziter Angabe der meisten Parametern und aktiviertem EWSTrace. Durch den Trace sehen Sie sowohl die abgesetzten Anfragen als auch die Rückantwort als XML/SOAP-Information
PS C:\test-ews> .\test-ews.1.0.ps1 ` -MailboxSMTP User1@msxfaq.local ` -Username User1 ` -Domain msxfaq ` -Password Password1 ` -EWSTrace ` -ServiceURL https://ews.msxfaq.local/ews/exchange.asmx <Trace Tag="EwsRequestHttpHeaders" Tid="6" Time="2014-10-27 07:28:02Z"> POST /ews/exchange.asmx HTTP/1.1 Content-Type: text/xml; charset=utf-8 Accept: text/xml User-Agent: ExchangeServicesClient/14.03.0032.000 Accept-Encoding: gzip,deflate </Trace> <Trace Tag="EwsRequest" Tid="6" Time="2014-10-27 07:28:02Z" Version="14.03.0032. 000"> <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m=" http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://sc hemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xml soap.org/soap/envelope/"> <soap:Header> <t:RequestServerVersion Version="Exchange2007_SP1" /> <t:TimeZoneContext> <t:TimeZoneDefinition Id="W. Europe Standard Time" /> </t:TimeZoneContext> </soap:Header> <soap:Body> <m:GetFolder> <m:FolderShape> <t:BaseShape>AllProperties</t:BaseShape> </m:FolderShape> <m:FolderIds> <t:DistinguishedFolderId Id="inbox" /> </m:FolderIds> </m:GetFolder> </soap:Body> </soap:Envelope> </Trace> <Trace Tag="EwsResponseHttpHeaders" Tid="6" Time="2014-10-27 07:32:19Z"> 200 OK Connection: Keep-Alive Transfer-Encoding: chunked request-id: 2240404d-4a71-4b79-b064-0a126cb7da2b X-CalculatedBETarget: exchange.msxfaq.local Strict-Transport-Security: max-age=10886400; includeSubDomains,max-age=10886400; includeSubDomains X-DiagInfo: EX01 X-BEServer: EX01 Cache-Control: private Content-Type: text/xml; charset=utf-8 Date: Mon, 27 Oct 2014 07:32:21 GMT Set-Cookie: exchangecookie=c6adbb3c4b974498b7b64dd05fbe548f; expires=Tue, 27-Oct -2015 07:32:22 GMT; path=/; HttpOnly,X-BackEndCookie=S-1-5-21-11949449-30417519- 71842111-1009=u56Lnp2e; expires=Mon, 27-Oct-2014 07:42:22 GMT; path=/ews; secure ; HttpOnly Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 Persistent-Auth: true X-Powered-By: ASP.NET X-FEServer: EX01 </Trace> <Trace Tag="EwsResponse" Tid="6" Time="2014-10-27 07:32:19Z" Version="14.03.0032 .000"> <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber=" 775" MinorBuildNumber="35" Version="V2_4" xmlns:h="http://schemas.microsoft.com/ exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/servi ces/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://w ww.w3.org/2001/XMLSchema-instance" /> </s:Header> <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="htt p://www.w3.org/2001/XMLSchema"> <m:GetFolderResponse xmlns:m="http://schemas.microsoft.com/exchange/servic es/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/t ypes"> <m:ResponseMessages> <m:GetFolderResponseMessage ResponseClass="Success"> <m:ResponseCode>NoError</m:ResponseCode> <m:Folders> <t:Folder> <t:FolderId Id="AAMkAGAl8uw==" /> <t:ParentFolderId Id="AxqBdxPwfQEa+eAIApY4A=" ChangeKey="AQAAAA==" /> <t:FolderClass>IPF.Note</t:FolderClass> <t:DisplayName>Posteingang</t:DisplayName> <t:TotalCount>3740</t:TotalCount> <t:ChildFolderCount>14</t:ChildFolderCount> <t:EffectiveRights> <t:CreateAssociated>true</t:CreateAssociated> <t:CreateContents>true</t:CreateContents> <t:CreateHierarchy>true</t:CreateHierarchy> <t:Delete>true</t:Delete> <t:Modify>true</t:Modify> <t:Read>true</t:Read> </t:EffectiveRights> <t:UnreadCount>11</t:UnreadCount> </t:Folder> </m:Folders> </m:GetFolderResponseMessage> </m:ResponseMessages> </m:GetFolderResponse> </s:Body> </s:Envelope> </Trace> Number or unread Messages : 11
Wenn die Daten nicht stimmen, dann sind die Fehlermeldungen meist aussagekräftig genug, um die Ursache zu beheben oder zu umschiffen.
Weitere Links
- EWS
- MAPI/CDO
- PowerShell
- Webservice
- Accessing The Information Store From PowerShell
http://blogs.technet.com/b/bill_long/archive/2010/04/06/accessing-the-information-store-from-PowerShell.aspx - MSDN: Introducing the Exchange Web Services Managed
API 1.0
http://msdn.microsoft.com/en-us/library/dd637749(EXCHG.80).aspx - Introducing the Exchange Web Services Managed API
1.0 Beta
http://blogs.technet.com/b/exchange/archive/2009/04/21/451126.aspx - Using the EWS Managed API with PowerShell
http://gsexdev.blogspot.com/2009/04/using-ews-managed-api-with-PowerShell.html - Create a folder under the Inbox if one doesn't
existing using PowerShell and the EWS Managed API
http://gsexdev.blogspot.com/2010/02/create-folder-under-inbox-if-one-doesnt.html - Using EWS to calculate the age of Items and affect
of archive and retention policies in Exchange 2010
http://gsexdev.blogspot.com/2011/04/using-ews-to-calculate-age-of-items-and.html -
AutodiscoverService.GetUserSettings
method
https://msdn.microsoft.com/de-de/library/microsoft.exchange.webservices.autodiscover.autodiscoverservice.getUsersettings(v=exchg.80).aspx - Using Autodiscover to get User settings
https://msdn.microsoft.com/en-us/library/office/dd633650(v=exchg.80).aspx - How to access the archive
folder when User’s mailbox is
On-Prem and the archive
mailbox is in the cloud.
https://blogs.msdn.microsoft.com/webdav_101/2015/07/27/how-to-access-the-archive-folder-when-Users-mailbox-is-On-Prem-and-the-archive-mailbox-is-in-the-cloud/ - Decrypt PowerShell Secure
String Password
https://blogs.technet.microsoft.com/heyscriptingguy/2013/03/26/decrypt-powershell-secure-string-password/