Get Microsoft Teams Meeting Attendance Report Through Graph API

In this post I'll show you how you can retrieve Teams meeting attendance reports as an Admin via Graph API.

Over a year ago I was asked if it’s possible to retrieve a Teams meeting attendance report if the organizer of the meeting isn’t available to get the report themselves. At the time, I created a quick and dirty script to get what was urgently needed but today I put it all in a nice and ready to use example.

Of course an organizer being out of office isn’t the only scenario why you’d need this. Another popular use case I can think of is to create an automation to automatically archive attendance reports for recurrent meetings.

First, let’s look at how an end user would access and view an attendance report.

TL; DR - I know what I’m doing, just give me the script already!

View Meeting Attendance Report as Organizer

Only meeting organizers have access to meeting attendance reports. To view an attendance report, organizers can simply open the meeting chat. Teams will automatically post the attendance report after a meeting has ended.

Organizer View Attendee View

Note that the attendance report is only shown in chat for the meeting organizers. Attendees can’t view see it. That’s also why we’re looking into how to get it through the Graph API today. Organizers also see a tab called Attendance. This is where they can view the report directly in Teams.

Attendance Tab

It’s also possible to download a CSV but it’s not very well structured which makes it kind of hard to further process the data.

CSV Export

Let’s switch gears and make some graph requests.

Get Meeting Attendance Report Through Graph PowerShell

Since we’re accessing data without a signed in user, we need an Entra ID application with appropriate application permissions.

Create a new Entra ID App Registration.

Note: You’ll need Global Admin access to grant the consent for your organization.

Go to the Entra ID Portal and click on App registrations under Applications in the left navigation menu.

App registrations

Then click + New registration.

New registration

Give your app registration a name and keep Accounts in this organizational directory only (“Org Name” only - Single tenant). Under Redirect URI (optional) select Public client/native (mobile & desktop) and enter http://localhost as redirect URI.

App registration properties

Click Register to create the app registration.

Copy the Application (client) ID and the Directory (tenant ID). You’ll need this later.

Copy Ids

Add Permissions

Navigate to API permissions in the left navigation pane and click + Add a permission.

API permissions Select Microsoft Graph Select Application permissions

Search for OnlineMeeting and expand the menus to select OnlineMeetingArtifact.Read.All and OnlineMeetings.Read.All.

Select permissions

Click Add permissions and then click Grant admin consent for “Org Name”.

Grant Consent Click Yes

Add a Client Secret

Navigate to Certificates & secrets in the left navigation pane. Under Client secrets (0) click + New client secret.

Client secrets

Give your secret a name and select after how many months it will expire.

Add a client secret

Copy the secret from the portal. It will only be shown once and you’ll need it later.

Copy secret

The configuration of the app registration is now complete.

Run the Script to get an Attendance Report

The script can be found in my Teams Phone Automation Repo on GitHub. If you want to make use of the secret encryption feature, you’ll need to clone the entire repo because of the dependencies of other files in the repo.

To be able to retrieve an attendance report from Microsoft Graph, we need a meeting id. Unfortunately, this is not your typical GUID you could easily find in TAC. But we can, however find it easy enough by passing a Join meeting ID.

Meeting Id example

Luckily, anyone that was invited to the meeting in question can view the Meeting ID and send it to you. Alternatively, the meeting invite could also be forwarded to you. The meeting Id is located below the join link.

Meeting ID in meeting invite body

Once you have this ID, you’re ready to get the attendance report through PowerShell.

Teams Application Access Policy

The Graph permissions alone are not enough to access the attendance report. We also need to create a new Teams Application Access Policy which includes the app id of the newly created Entra ID app and grant it to the meeting organizer. This is how you can do it in PowerShell.

1
2
# Create a new Teams Application Access Policy
New-CsApplicationAccessPolicy -Identity $applicationAccessPolicyName -AppIds $AppId -Description "Access Meeting Data as Entra ID app on behalf of user"

New-CsApplicationAccessPolicy

1
2
# Assign a Teams Application Access Policy to a user
Grant-CsApplicationAccessPolicy -Identity $UserId -PolicyName $applicationAccessPolicyName 

Grant-CsApplicationAccessPolicy

But the script does all of this automatically for you.

Script output PowerShell output

Unassign Teams Application Access Policy

If you only want to get an attendance report once and need to remove the application access to another user’s meeting details, you can unassign the policy again by using this code.

1
Grant-CsApplicationAccessPolicy -Identity $UserId -PolicyName ""

Script Prompts

When the script runs for the first time it will ask you for your app secret. Paste it into the terminal. This will save your secret in an encrypted format. Only the signed in user (in Windows) can decrypt it and it can only be decrypted on the same machine on which it was encrypted. You’ll also be asked to sign into Teams PowerShell as well.

Paste secret Sign into Teams

Results

Once the Application Access Policy already exists and was already granted to the organizer, the console output looks much less cluttered. The report will be saved to the current directory and it’s filename will include the subject of the meeting.

Script output

If there are multiple attendance reports for a meeting, like when a meeting already ended and someone joined again after that or when it’s a recurring meeting, all reports will be combined into a single CSV. The CSV does include the report id in the last column.

Let’s compare the CSV that was downloaded from the Teams client versus the one from my script.

CSV Export from Teams CSV Export from Script

As you can see, the output from my script gives you a nicely structured CSV which lists 1 participant per row so you can easily import it into other systems without manually changing the structure of the file. Because of that, I decided to create separate files for meeting/attendance summaries.

Meeting Summary from Script

Summary

I personally believe that it’s very easy for organizers to access the reports themselves in Teams but having the possibility to get them as an admin via PowerShell as well is certainly a welcome addition to my script toolbox. This will be especially useful in case you’re asked to export attendance reports on a regular basis. While the fact that you need to know the unique meeting id before you can get an attendance report makes it a bit harder to truly automate this or you may have to chase other attendees for it, if you weren’t invited to the meeting yourself but overall, the join meeting Id should be easy enough to retrieve.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Hosted on GitHub Pages
Built with Hugo
Theme Stack designed by Jimmy