REST - Representational State Transfer
Das HTTP ein weit verbreitetes Transportmittel für Informationen ist, weiß mittlerweile auch der normale Anwender durch die Adressliste im Browser. HTTP kann aber auch zwischen Diensten genutzt werden und hier ist die REST - Representational State Transfer eine immer wichtigere Möglichkeit die Daten anzufordern und darzustellen.
Exchange hat selbst On-Premises eine Exchange REST API für Mail, Kontakt, Termine, die aber nicht direkt sondern nur über die Cloud angesprochen werden kann. Siehe dazu Graph und Exchange On-Premises
Der Request
Ein HTTP-Client fordert Daten in der Regel durch einen GET oder POST an, seltener kommt Verben wir PUT, PATCH, DELETE, HEAD, OPTIONS, CONECT oder TRACE zum Einsatz. Über die URL und ggfls. Daten im Body der Anforderung erhält der Server die Information, die dieser zur Beantwortung der Frage benötigt. Im einfachsten Fall ist es einfach die URL selbst, die ausreichend Informationen enthält.
Der wichtige Aspekt hierbei ist, dass der Request alle Informationen enthält und keine Abhängigkeiten von vorherigen Anfragen oder Stati vorhanden sind. Wenn ein Request genau so wiederholt gestellt wird und sich der Datenbestand nicht verändert hat, kommt auch wieder das gleiche Ergebnis zurück.
Eine REST-Schnittstelle ist damit deutlich einfacher als z.B. ein WebService. Bei einem Exchange WebService ist es z.B. so, dass der Client sich erst anmeldet und dann z.B. ein Postfach und einen darin enthaltenen Ordner erreichen muss, ehe dann das einzelne Element abgefragt werden kann.
Die Rückgabe
Der Service verarbeitet die Information und liefert die Daten zurück. Ohne die Beschreibung von REST sind hier sehr viele Optionen möglich und wurden in der Vergangenheit genutzt.
- Text-Ergebnis
Es gab Webservices, die einfach einen Text zurück geliefert haben. So liefert z.B. der Exchange Health Check auf einen Anfragen auf https:\\<serverfqdn>\owa\healthcheck.htm einfach nur einen "200OK". - Webeites zum Parsen
Andere Services, die per HTTP erreichbar sind, liefern dennoch nur eine normale "Webseite". Per Skript kann man versuchen, dort die gewünschten Informationen "abzugreifen". Das habe ich z.B. bei PRTG:Kostal so gemacht - XML-Antworten
Es gibt aber auch ohne den "REST"-Begriff schon Webdienste, die als Antwort eine XML-Struktur ausliefern. Das sind neben vielen "WebServices" auch einfachere Systeme wie z. B. der MIBI Temperatur-Sensor, - XML/JSON
Eine sehr schöne Einführung habe ich auf YouTube gefunden
REST API concepts and examples
https://www.youtube.com/watch?v=7YcW25PHnAA
REST in Produkten
Aufgrund der Einfachheit von REST für den Client rüsten immer mehr Hersteller ihre Produkte um eine RESTful API nach. Hier ein paar Beispiele
Es gibt noch sehr viele weitere Anbieter und ich denke REST ist die nächste API, die WebServices verdrängen kann.
Einsatz mit PowerShell (PS 3.0 oder höher)
Ab PowerShell 3.0 können Sie sehr viele Aufgaben als HTTP-Client in einer Zeile lösen, z.B.: den Download einer Datei.
$data= Invoke-WebRequest ` -Uri "http://www.msxfaq.de" ` -Outfile msxfaq-homepage.htm
Analog dazu können Sie auch Daten per POST an eine Webseite hochladen.
$data= Invoke-WebRequest ` -Method post ` -Uri "http://localhost:81/post.txt" ` -Body "bodtest"
Das macht es natürlich schon sehr viel einfacher mit einem Webserver zu interagieren.
- Invoke-WebRequest
http://technet.microsoft.com/en-us/library/hh849901.aspx - Invoke-RestMethod
http://technet.microsoft.com/en-us/library/hh849971(v=wps.620).aspx - PS JSON
Die Antwort im Erfolgsfalle ist ein HtmlWebResponseObject.
- HtmlWebResponseObject Class
http://msdn.microsoft.com/en-us/library/microsoft.PowerShell.commands.htmlwebresponseobject(v=vs.85).aspx
Interessant sind hier bei die beiden Properties "StatusCode" und "StatusDescription". Der Inhalt ist in dem Property "Content". Wer dem kompletten HTML-Inhalt samt Header benötigt, nutzt "RawContent". Interessanter sind aber vor allem die vorgearbeiteten Properties wie z.B."Links", welches alle Hyperlinks ausgibt.
Hinweis
Die Rückgabe enthält nur dann ein Objekt, wenn
die Abfrage erfolgreich war. Fehler werden immer
mit einer "Exception" abgefangen. Erwarten Sie
also nie in $data.Statuscode einen 401 o.ä.
Achtung: Invoke-Webrequest
nutzt per Default DOM des IE. Wenn dieser nicht
installiert oder limitiert ist, kann das Parsen
nicht funktionieren. Nutzen Sie dann den
Parameter "-UseBasicParsing".
Dummerweise werden dann wohl nur Links, Forms,
Images und Header auseinander genommen aber das
Feld "ParsedHTML" bleibt leer.
Achtung: Beide Commandlets senden nicht zwingend den kompletten Request in einem Paket. Es ist durchaus erlaubt den Request auf mehrere Pakete aufzuteilen und dem Ziel über das Feld "Content-Length" mitzuteilen, wie groß die Daten sind. Das Ziel muss dann mit einem "100 Continue" eine Zwischenbestätigung senden. Leider "verstehen" das gerade kleine Geräte das nicht immer, wie ich auf PRTG Edimax SP2101W z.B. herausgefunden habe.
- PS JSON
- Friday Fun: It’s PowerShell,
Baby!
http://jdhitsolutions.com/blog/2013/06/friday-fun-its-PowerShell-baby/ - Web Scraping with PowerShell
http://teusje.wordpress.com/2012/12/29/web-scraping-with-PowerShell/ - InvokeRestMethod für the
Rest of us
http://blogs.technet.com/b/heyscriptingguy/archive/2013/10/21/invokerestmethod-for-the-rest-of-us.aspx - Use PowerShell to Work with
SkyDrive für Powerful Automation
http://blogs.technet.com/b/heyscriptingguy/archive/2013/07/02/use-PowerShell-to-work-with-skydrive-for-powerful-automation.aspx
REST und Authentifizierung
Rest ist einfach und auch wenn der Unterbau wieder HTTP ist, so sind nicht alle REST-Services vollständig. Ich habe das bei der Abfrage der RestAPI von MobileIron gemerkt, von der ich die Liste der Geräte erhalten wollte. Mit "Invoke-RESTMethod" verbindet sich die PowerShell erst einmal anonym und erwartet dann, dass der Webserver nicht nur einen 401 sendet, sondern auch die möglichen Anmeldeverfahren mitteilt. Wenn dies aber unterbleibt, weiß der Client nicht wie er weiter machen soll. So etwas können Sie recht einfach per Fiddler sehen. Hier ein Beispiel.
Sie sehen oben den Request und unten die Antwort mit dem 401 aber ohne Hinweise auf die verfügbaren Authentifizierungsmethoden. In dem Fall können sie nur "Raten" und die Anmeldedaten auf Verdacht mit senden. Da dies mit Invoke-RESTMethod nicht über den Parameter "-Credentials" möglich ist, müssen Sie die Authentifizierung im Header selbst unterbringen. Das ist aber nicht sonderlich schwer, wenn man es mit "BASIC-Authentication" zu tun hat. Hier ein Beispiel:
$User = "Username" $pass = "PassWord1+" $basicauth=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($User+":"+$pass)) $headers=@{} $headers.Add("Authorization","Basic $basicauth") $headers.Add("ContentType","application/json") $result = Invoke-RestMethod -URI ('https://mdmserver/api/v2/ping') -headers $headers
Sie sollten natürlich das Kennwort nicht im Code verstecken und bei der Nutzung von "Basic" sollten Sie auf ein HTTPS achten. Das Kennwort kann sonst sehr einfach abgefischt werden.
- How to convert string to Base64 and vice
versa using Powershell
http://vstepic.blogspot.de/2013/02/how-to-convert-string-to-base64-and.html
Weitere Links
- Graph und Exchange On-Premises
- PS SOAP
- PS HTTPClient
-
PS JSON
Wie kann ich mit PowerShell und JSON-Daten arbeiten? -
Outlook REST API v2.0 Deprecation Notice
(30. Nov 2022)
https://developer.microsoft.com/en-us/office/blogs/outlook-rest-api-v2-0-deprecation-notice/ - Representational State Transfer
https://de.wikipedia.org/wiki/Representational_State_Transfer - Parsing REST Services XML Responses (C#)
https://msdn.microsoft.com/en-us/library/hh534080.aspx -
Exchange 2016: REST Api für lokale
Exchange Server schon verfügbar?
https://www.frankysweb.de/exchange-2016-rest-api-fr-lokale-exchange-server-schon-verfgbar/ -
Invoke-RestMethod does not strip
Authorization Headers
https://GitHub.com/PowerShell/PowerShell/issues/2227 -
Using the Office365/Exchange 2016 REST
API to access Mailbox data using PowerShell
Part1
http://gsexdev.blogspot.com/2017/02/using-office365exchange-2016-rest-api.html -
Calling a Rest (Json) API with PowerShell
https://www.lavinski.me/calling-a-rest-json-api-with-powershell/ -
Use PowerShell to Consume a ProfitBricks
REST API
https://devops.profitbricks.com/tutorials/use-powershell-to-consume-a-profitbricks-rest-api/ -
Using Windows PowerShell as a REST Client
http://www.datacore.com/RESTSupport-Webhelp/using_windows_powershell_as_a_rest_client.htm -
Using PowerShell behind a proxy
http://martin.hoppenheit.info/blog/2015/using-powershell-behind-proxy/ -
How to define the basic HTTP
authentication using CURL correctly?
http://stackoverflow.com/questions/25969196/how-to-define-the-basic-http-authentication-using-curl-correctly -
Windows PowerShell and the Text-to-Speech REST API
Part 1: https://blogs.technet.microsoft.com/heyscriptingguy/2018/02/28/windows-powershell-and-the-azure-text-to-speech-rest-api-part-1/
Part 2 https://blogs.technet.microsoft.com/heyscriptingguy/2018/03/15/windows-powershell-and-the-text-to-speech-rest-api-part-2/