Microsoft Graph REST API - Outlook Calendar with Powershell
Hallo zusammen,
Ich habe ja in der Vergangenheit viele Dinge über PowerShell und die Exchange Webservices Management API gemacht. Mit der Abschaltung von Basic Authentication wird das aber immer schwieriger. Früher gab es ja noch die Outlook REST API. Aber selbst die Outlook REST API V2.0 wird anscheinend nicht mehr weiterentwickelt. https://developer.microsoft.com/en-us/office/blogs/migrating-from-outlook-rest-api-v1-0-to-microsoft-graph/
Version 1.0 of theOutlook REST APIwas launched in 2015 to provide API access to mail, calendar, contacts, and other data from Exchange Online, with support for Basic Authentication. Over time, we’ve released major enhancements in Outlook REST API v2.0 and Microsoft Graph, both of which provide richer features, and better performance and reliability than Outlook REST API v1.0. Both Outlook REST API v2.0 andMicrosoft Graphuse OAuth 2.0 for authentication and authorization, which is a more secure and reliable way than Basic Authentication to access data. With the planned deprecation of the Outlook REST API v1.0, you can update your app to Microsoft Graph and leverage all the new functionality available there. This article will give you guidance on the process of upgrading from the Outlook v1.0 REST API to theMicrosoft Graph*REST API and well as pointing some of the key differences.
Microsoft Graph
Also habe ich mich mal mit der Microsoft Graph API und dem Zugriff auf die Outlook Kalender beschäftigt.
Ein guter Einstieg ist auch immer der Graph Explorer um die Querys zu testen.
Der Graph Explorer ist als im Azure Active Directory als Enterprise Application eingetragen und benötigt je nach Zugriffe ebenfalls Berechtigungen mit Admin Consent.
Für den Zugriff via PowerShell braucht es eine registrierte App im Azure Active Directory. Für den Zugriff auf den Kalender brauche ich folgende Rechte.
Microsoft.Graph:
- Calendars.Read
- Calendars.ReadWrite
Aber denkt daran, diese Rechte sind fast genau so mächtig wie Exchange Impersonation. Das heisst, damit habe ich die Berechtigungen auf alle Kalender in der Organisation zuzugreifen und dort zu schreiben und zu löschen.
Authentication und AccessToken
Das schwierigste ist jeweils sich zu Authentifizieren um einen Accesstoken zu bekommen. Mit folgendem Code klappt es.
#Variables
$ClientID = "9a8d72df-686a-496c-bc5e-a147d813abd1"
$ClientSecret = "ClientSecret"
$tenantID = "icewolfch.onmicrosoft.com"
$scope = "https://graph.microsoft.com/.default"
$authority = "https://login.microsoftonline.com/$tenantID/oauth2/v2.0/token"
$Body = @{
"grant\_type" = "client\_credentials";
"client\_id" = "$ClientID";
"client\_secret" = "$ClientSecret";
"scope" = "$scope";
}
#Get AccessToken
$result = Invoke-RestMethod -Method POST -uri $authority -Body $body
$AccessToken = $result.access_token
Get Calendar
Ich lasse mir mal die Kalenderfolder von meinem Benutzer anzeigen. Beim Aufruf muss ein Header mit dem AccessToken mitgegeben werden.
$mailbox = "a.bohren@icewolf.ch"
$headers = @{"Authorization" = "Bearer "+ $AccessToken}
$uri = "https://graph.microsoft.com/v1.0/users/$Mailbox/Calendars"
$Calendars = Invoke-RestMethod -Method GET -uri $uri -headers $headers
$Calendars.Value | fl name,id
List Events
Mit dem folgenden Codebeispiel, kann man sich die Kalendereinträge einer Mailbox anzeigen.
$mailbox = "a.bohren@icewolf.ch"
$headers = @{"Authorization" = "Bearer "+ $AccessToken}
$uri = "https://graph.microsoft.com/v1.0/users/$Mailbox/calendar/events"
Invoke-RestMethod -Method GET -uri $uri -headers $headers
$Events = Invoke-RestMethod -Method GET -uri $uri -headers $headers
$Events | Get-Member
Wie man sieht, gib es
$Events.Value | ft subject,start,end,location
TimeZone
Für Termine braucht man immer auch noch die TimeZone. Die Liste kann man sich mit folgendem Befehl anschauen:
Get-TimeZone -ListAvailable | ft id, Displayname
Create Event
Dann machen wir doch mal einen Kalender Eintrag.
$mailbox = "a.bohren@icewolf.ch"
$headers = @{
"Authorization" = "Bearer "+ $AccessToken;
"Prefer" = 'outlook.timezone="W. Europe Standard Time"';
"Content-type" = "application/json"
}
#Create JSON Object
$json = @"
{
"subject":"Graph API Example",
"body": {
"contentType" : "HTML",
"content" : "Write Graph API Powershell Script"
},
"start": {
"dateTime" : "2020-04-30T07:00:00",
"timeZone" : "W. Europe Standard Time"
},
"end": {
"dateTime" : "2020-04-30T08:00:00",
"timeZone" : "W. Europe Standard Time"
},
"location":{
"displayName" : "HomeOffice"
}
}
"@
$uri = "https://graph.microsoft.com/v1.0/users/$Mailbox/calendar/events"
Invoke-RestMethod -Method POST -Uri $uri -Headers $headers -Body $json
Der Termin wurde im Kalender eingetragen
Get Event
Beim Erstellen des Eintrags habe ich mir die ID gemerkt. Damit kann man direkt auf den Eintrag zugreifen
$id = "AQMkADU4NGU4M2ViLWM5NjctNGI0YS05ZmJhLTIyADdmYWI0MjRkYmQARgAAAzqJ2GWaRBxKv-EJWOBGbRAHAEZu88iLm85MjHqnrJ10b8oAAAIXkwAAAcb9AhgmYESSPal9iQNu6wAB0zikmgAAAA=="
$mailbox = "a.bohren@icewolf.ch"
$headers = @{"Authorization" = "Bearer "+ $AccessToken}
$uri = "https://graph.microsoft.com/v1.0/users/$Mailbox/calendar/events/$id"
Invoke-RestMethod -Method GET -uri $uri -headers $headers
$Events = Invoke-RestMethod -Method GET -uri $uri -headers $headers
Update Event
Auch hier nutze ich wieder die ID um auf das Event zuzugreifen und dieses zu aktualisieren.
$id = "AQMkADU4NGU4M2ViLWM5NjctNGI0YS05ZmJhLTIyADdmYWI0MjRkYmQARgAAAzqJ2GWaRBxKv-EJWOBGbRAHAEZu88iLm85MjHqnrJ10b8oAAAIXkwAAAcb9AhgmYESSPal9iQNu6wAB0zikmgAAAA=="
$mailbox = "a.bohren@icewolf.ch"
$headers = @{
"Authorization" = "Bearer "+ $AccessToken;
"Content-type" = "application/json"
}
$json = @"
{
"subject" : "Graph API Example Update",
},
{
"location":{
"displayName" : "Office Bern"
}
}
"@
$uri = "https://graph.microsoft.com/v1.0/users/$Mailbox/calendar/events/$id"
Invoke-RestMethod -Method PATCH -Uri $uri -Headers $headers -Body $json
Das Subject wurde geändert, jedoch die Location wurde nicht angepasst… Vielleicht ist da noch was an meinem JSON falsch.
Delete Event
Auch hier nutze ich wieder die ID um den Termin zu löschen
$id = "AQMkADU4NGU4M2ViLWM5NjctNGI0YS05ZmJhLTIyADdmYWI0MjRkYmQARgAAAzqJ2GWaRBxKv-EJWOBGbRAHAEZu88iLm85MjHqnrJ10b8oAAAIXkwAAAcb9AhgmYESSPal9iQNu6wAB0zikmgAAAA=="
$mailbox = "a.bohren@icewolf.ch"
$headers = @{"Authorization" = "Bearer "+ $AccessToken}
$uri = "https://graph.microsoft.com/v1.0/users/$Mailbox/calendar/events/$id"
Invoke-RestMethod -Method DELETE -uri $uri -headers $headers
Et voila, der Termin ist wieder weg.
Fazit: Ich hoffe das hat euch einen kleinen Überblick gegeben und hilft auch andern beim Einsteigen in den Umgang mit Microsoft Graph mit PowerShell.
Grüsse
Andres Bohren














