Many organizations find it helpful to implement some kind of automation around user calendars.
The purpose could be tracking productivity, updating notification boards, seeing trends, etc.
With Microsoft Graph PowerShell, it’s pretty easy to access user calendars – if you know how to do it 🙂
Here’s a step-by-step guide:
Scripting Office 365 Calendars: Step-by-Step Guide
To enable programmatic access to all calendars in your organization, you need to implement the following:
- Generate a certificate to be used for OAuth2 authentication
- Set up a client application
- Assign API permissions to the application
- Set up a certificate identity on the application
1. Generate a Certificate to Be Used for Oauth2 Authentication
With PowerShell, you can quickly generate a self-signed certificate which works just fine for application authentication.
You’ll need two files from the certificate:
- A .pfx file – includes the private key and is stored securely in the personal certificate store of your scheduling account on the scheduling server.
- A .cer file – includes only the public key and is uploaded to the Azure App to allow you to authenticate using the corresponding (secret) private key.
Generate a new certificate and export the .pfx and .cer files using the following code:
# Create certificate with expiry of 5 years
$mycert = New-SelfSignedCertificate -DnsName "easy365manager.com" -CertStoreLocation "cert:\CurrentUser\My" -NotAfter (Get-Date).AddYears(5) -KeySpec KeyExchange
# Export certificate to .pfx file
$mycert | Export-PfxCertificate -FilePath C:\tmp\ExoAutomateCert.pfx -Password $(ConvertTo-SecureString -String "$omeP@ssw0rd" -AsPlainText -Force)
# Export certificate to .cer file
$mycert | Export-Certificate -FilePath C:\tmp\ExoAutomateCert.cer
The certificate is created in the personal certificate store of the user running the code.
If you plan to automate scripts using the logged-in account on the logged-in system, you won’t need the .pfx file (except for backup).
To use the certificate on another system/user account, you must log in interactively and import the certificate from the .pfx file.
The .cer file will be used to set up authentication on the Azure App in a later step.
2. Set Up a Client Application
You must log in to the Azure Portal to set up a new Azure Application. Then, select Azure Active Directory, click on App registrations, or follow this direct link.
From there, you can create a new App registration by clicking on New registration:
Complete the application registration:

The new Azure Application has now been created:
Notice the Application (client) ID. This is what we will use as the -AppId parameter when connecting to Exchange Online with PowerShell.
3. Assign API Permissions to the Application
We’ll be using the Graph API to access user calendars. This is much easier to use than older methods like Exchange Web Services (EWS).
Select API permissions, click on Add a permission, and select Microsoft Graph:
Select Application permissions:
Then scroll down to find Calendars permissions. Select Calendars.Read if you’re only going to review/export information:
We now have the permissions needed to access calendar information. If you also want your script to extract user information, you can add the following permissions:
Click on Add permissions to commit the new API permissions.
Then grant Admin Consent to the new permissions:

The status of the permissions will change to Granted, and the new client application is now set up.
We only need to grant access to use it.
4. Set Up a Certificate Identity on the Application
To enable authentication using the certificate generated in step 1, we need to perform the following steps:
Click on Certificates & secrets, click on Certificates, click on Upload certificate, browse to the .cer file from step 1, add a description and click on Add:
You’ll now see the certificate in the list, including the thumbprint that we’ll be using as a parameter in our script:
Read Calendar Information Using Microsoft Graph PowerShell
We’re ready to rock’n’roll!
Use the Microsoft Graph PowerShell module to access the user calendars.
Connect to your new client application with the certificate using the following command:
PS C:\> Connect-MgGraph -TenantId "8a35f394-855d-4d13-9f6f-86d8eb24dc6b" -ClientId "23b3f624-502d-42fb-83ac-ea9f6aff9e5b" -CertificateThumbprint "08451D7079F093EBB2A2CB0266C885ECA098DD9E" Welcome To Microsoft Graph!
To extract calendar information, use the Get-MgUserCalendarView CmdLet.
The following example lists all calendar entries for today for the user Hans C. Ørsted (only one entry is shown):
PS C:\> $StartDate = Get-Date -Date 00:00:00 PS C:\> $EndDate = Get-Date -Date 23:59:59 PS C:\> Get-MgUserCalendarView -UserId hans.c.orsted@azure.skrubbeltrang.com -CalendarId "Calendar" -StartDateTime $StartDate -EndDateTime $EndDate | fl AllowNewTimeProposals : True Attachments : Attendees : {Microsoft.Graph.PowerShell.Models.MicrosoftGraphAttendee, Microsoft.Graph.PowerShell.Models.MicrosoftGraphAttendee, Microsoft.Graph.PowerShell.Models.MicrosoftGraphAttendee} Body : Microsoft.Graph.PowerShell.Models.MicrosoftGraphItemBody BodyPreview : Do some more testing on electro magnetism. Calendar : Microsoft.Graph.PowerShell.Models.MicrosoftGraphCalendar Categories : {} ChangeKey : xa95c+RziUeacUESMPKGkwAAGGtkxw== CreatedDateTime : 11/8/2022 7:19:51 AM End : Microsoft.Graph.PowerShell.Models.MicrosoftGraphDateTimeZone Extensions : HasAttachments : False HideAttendees : False ICalUId : 040000008200E00074C5B7101A82E00800000000000135B14AF3D801000000000000000010000000D7E511407918FD4F9318BD4EEDFB3229 Id : AAMkAGY5MjM3MjVmLTcxMzQtNDEwNC1iNDQwLTU1NjNhOGRmYzM5ZABGAAAAAAAHk64FGa4vQJkMsperiKxZBwDFr3lz5HOJR5pxQRIw8oaTAAAAAAENAADFr3lz5HOJR5pxQRIw8oaTAAAYa3q5AAA= Importance : normal Instances : IsAllDay : False IsCancelled : False IsDraft : False IsOnlineMeeting : False IsOrganizer : True IsReminderOn : True LastModifiedDateTime : 11/8/2022 7:21:52 AM Location : Microsoft.Graph.PowerShell.Models.MicrosoftGraphLocation Locations : {Science room 23} MultiValueExtendedProperties : OnlineMeeting : Microsoft.Graph.PowerShell.Models.MicrosoftGraphOnlineMeetingInfo OnlineMeetingProvider : unknown OnlineMeetingUrl : Organizer : Microsoft.Graph.PowerShell.Models.MicrosoftGraphRecipient OriginalEndTimeZone : Romance Standard Time OriginalStart : OriginalStartTimeZone : Romance Standard Time Recurrence : Microsoft.Graph.PowerShell.Models.MicrosoftGraphPatternedRecurrence ReminderMinutesBeforeStart : 15 ResponseRequested : True ResponseStatus : Microsoft.Graph.PowerShell.Models.MicrosoftGraphResponseStatus Sensitivity : normal SeriesMasterId : ShowAs : busy SingleValueExtendedProperties : Start : Microsoft.Graph.PowerShell.Models.MicrosoftGraphDateTimeZone Subject : Meeting with assistant TransactionId : Type : singleInstance WebLink : https://outlook.office365.com/owa/?itemid=AAMkAGY5MjM3MjVmLTcxMzQtNDEwNC1iNDQwLTU1NjNhOGRmYzM5ZABGAAAAAAAHk64FGa4vQJkMsperiKxZBwDFr3lz5HOJR5pxQRIw8oaTAAAAAAENAADFr3lz5HOJR5pxQRIw8oaTAAAYa3q5AAA%3D&exvsurl=1&path=/calendar/item AdditionalProperties : {[@odata.etag, W/"xa95c+RziUeacUESMPKGkwAAGGtkxw=="]}
Besides a lot of technical information, you’ll see useful properties in the above output:
- Start
- End
- Subject
- BodyPreview
- Attendees
- Location
and more.
Have fun creating applications and scripts with calendar integration!