Automatically Forward All-Company Meetings to New Hire Calendars Using Graph API
Automating the employee onboarding process is pretty much the equivalent of trying to teach your 2008 Toyota Yaris how to drive itself down the street. It's probably not impossible, but is your up-front time investment going to outweigh the benefit? I don't have all the answers, but hopefully this post will help you cross off one of the more frustrating problems with employee onboarding.
So let's talk about all-company meetings.
When your company hires someone, there's likely some all-company meetings hosted on some sort of shared calendar or resource calendar that should be added to the employee's personal calendar.
If you're managing meeting forwards at all, you are likely doing this manually. Maybe your solution involves using a .ics file? Yeah, I thought so.
We can be better.
The solution I'm about to show you is mind-numbingly simple once you get the hang of it. We're going to use Microsoft Graph API in Powershell to grab a calendar object, and forward it to another user. I chose Graph API for the simple reason that it's easy AF, and requires far less manual steps and lines of code than a standard Exchange Powershell approach.
If you're not familiar with Graph API, get yourself familiar real quick: https://docs.microsoft.com/en-us/graph/
If you're not familiar with making API requests in Powershell: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-6
This process has some pre-requisites before we can get to coding:
1. Azure Native App with the following delegated API permissions for Graph:
a. User.Read, User.ReadWrite, User.ReadBasic.All, User.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All, Directory.AccessAsUser.All
2. The executing user account needs full access delegation to the target user calendar
3. Both accounts need to be a member of an Exchange admin role that allows Application Impersonation.
Creating an Azure Native App:
Graph API requires a set of special permissions to your tenant in order to make a successful authentication request to the API endpoint before you can begin using it to view and manage objects. I've documented this process in a post: Password Based OAuth Authentication in Powershell with Graph API.
Adding full access delegation to a user calendar:
The account executing the script in this article needs to have full access delegation to the target calendar. You can find out how to do that here.
Adding members to Application Impersonation role:
Okay, now that we have our permissions configured within our tenant, let's get to the fun part. Code!
The first thing we have to do is set the web request protocol in Powershell, and authenticate to Graph:
After running, $Token should return your authentication token. You will use this to send requests to the Graph endpoints in the following steps.
Next, we have to grab the Event ID of the target event. To do so, we need to know the username of the event owner:
Formatting the URL gets a little sticky here, since we added a filter with a protected character: "$". You can see that I had to manually format the $Filter string.
$Request should be piped to ConvertFrom-JSON, so that we can work with the values a little easier to grab just the event ID string.
If the user has multiple events on their calendar, this request will return the Event IDs for each event. Since we're looking to forward particular events, we'll need to filter out the events somehow. The easiest way to do this is probably by the event Subject.
So, we'll grab a Subject for an event in $ForwardSubject, check all events for a match using the Event IDs, and then forward the one that matches. We'll do this in a ForEach loop:
You can see that the $Body had to be constructed a little different than our other requests. You can learn more about Body requirements from the Graph API documentation, and then test them outside of Powershell with an API request program like Postman.
Finally, if $SendResult returns a 202 response code, you've just successfully forwarded an event using Graph! To make this programmatic, you can set it up as a Scheduled Task, or better yet, use an Azure Automation account.
Here's the full script:
You can find this and more on my GitHub here.