Changing the default settings for Teams assignments using service accounts
First published:
Last updated:
When managing huge amounts of teams classes, individually visiting each class team to change the assignment deadlines is out of the question. Ideally we'd be able to do this with Graph API, but unfortunately at time of writing the official endpoint for assignments PATCH /education/classes/{id}/assignmentDefaults is broken! To get around this we're going to use a user account with the correct permissions to visit each team and change the default assignment deadline. This can be done with a service account, which is a user account that logs into Teams and performs actions on behalf of the user.
This is not an official recommended method, but as the official way doesn't work currently it's the working method. Using service accounts means you will be rate limited more, but I haven't had any issues with this method as of yet.
The default assignment deadlines (and any other settings you'd like to change) can be found in the teams assignment settings. To get to this page, go to the assignments tab in a team and click on the cogwheel in the top right corner.
There are 7 settings we can change here, and I'll give the syntax and API endpoint needed for changing each one as well as the assignment deadline.
Setting up the service account
I would highly recommend not using any account that already exists, as joining more than a thousand teams will slow down the Teams client to a crawl. The new user account doesn't need anything more than the teams license.
Once the account is created, you can get the users ID by checking the URL of the users profile page. The ID is the last part of the URL, after the last slash. It will look something like this: 12345678-1234-1234-1234-123456789012
We can then add the user to all the teams classes as an owner (or as Microsoft calls it a teacher, but there is no functional difference) with the following powershell script. If you haven't used powershell with GraphAPI before you'll need to install the module with Install-Module Microsoft.Graph.
$scopes = "Group.Read.All", "User.ReadBasic.All", "TeamMember.ReadWrite.All"
Connect-MgGraph -Scopes $scopes -NoWelcome
$UserID = Read-Host -Prompt "Enter the user ID of the user to add to class teams"
"Getting teams..."
$teamRequest = @{ Uri = "https://graph.microsoft.com/v1.0/teams?`$select=id"; Method = 'Get' }
$teams = while ($teamRequest.Uri) {
$teamResponse = Invoke-MgGraphRequest @teamRequest
$teamRequest.Uri = $teamResponse.'@odata.nextLink'
$teamResponse.value
}
$classes = $teams | ForEach-Object -Begin { $progress = 0 } -Process {
$uri = "https://graph.microsoft.com/v1.0/teams/$($_.id)?`$select=specialization,isArchived"
$teamRequest = Invoke-MgGraphRequest -Uri $uri -Method Get
$specialization = $teamRequest.specialization
$isArchived = $teamRequest.isArchived
if ($isArchived -eq $false -and $specialization -eq "educationClass") {
$_
}
$progress++
Write-Progress -Activity "Filtering teams" -Status "Teams filtered: $progress out of $($teams.Count)" -PercentComplete (($progress / $teams.Count) * 100)
}
$confirmation = Read-Host -Prompt "Add user to $($classes.Count) active classes? (y/n)"
if ($confirmation -ne "y") { exit }
"Adding user to teams..."
$classes | Foreach-Object -Begin { $progress = 0 } -Process {
$uri = "https://graph.microsoft.com/v1.0/teams/$($_.id)/members"
$userUri = "https://graph.microsoft.com/v1.0/users/$UserID"
$body = @{
'@odata.type' = 'microsoft.graph.aadUserConversationMember'
'roles' = @('owner')
'[email protected]' = $userUri
}
Invoke-MgGraphRequest -Uri $uri -Method Post -Body $body > $null
$progress++
Write-Progress -Activity "Adding user to teams" -Status "Teams added to: $progress out of $($classes.Count)" -PercentComplete (($progress / $classes.Count) * 100)
}
Once the script has run (which may take a while depending on how many teams you have) you can check the users profile page on the teams admin console to check that the user has been added to all the teams classes you expected. If you have an excess of 5000 total teams you may want to remove the confirmation prompt and just run the script overnight as although it will only add the service account to class teams, it has to check every team in the tenant to find the specialized ones.
Finding the settings to change
Next up we can start changing the settings. The settings are changed with a PATCH request to the PATCH https://assignments.onenote.com/api/v1.0/edu/classes/$($_.id)/defaultsAndSettings endpoint. The body of the request is a JSON object with the settings we want to change. The settings I'll be changing here are default due time, whether students are added to assignments that are still active but created before they joined the team, and whether assignments should be automatically added to the students calendar. The settings can be changed in the same way with the following syntax:
# Default times assignments are due: "dueTime" = __"HH:MM"__ (24 hour format) #dd students to assignments created before they joined the team: "addedStudentAction" = $True__ or $False__ # Add assignments to calendars: "addToCalendarActionAsEnum" = "none", "studentsOnly", "studentsAndPublisher" or "studentsAndTeachers" #Enable late submission notifications for teachers: "enableLateSubmissionNotifications" = $True or $False
To find these settings we can inspect the network traffic when changing the default settings in the Teams. The settings are found in the Request Payload and the authorization token is found in the Request Headers which we'll need for the next step.
Changing the settings
Once we have the requests we want to make, edit the script below to include the settings you want to change. The script will prompt you for your user ID and then the token you copied from the network traffic.
$scopes = "User.Read.All"
Connect-MgGraph -Scopes $scopes -NoWelcome
$userID = Read-Host -Prompt "Enter the user ID of the service account"
$token = Read-Host -Prompt "Enter the user token taken from browser"
if (-Not $token.StartsWith("Bearer ")) {
$token = "Bearer " + $token
}
$res = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/users/${userID}/joinedTeams?`$select=id" -Method Get
$classes = $res.value
$header = @{
'Authorization' = "${token}"
'Content-Type' = 'application/json'
'Accept' = 'application/json'
}
## \/ Change the settings here \/ ##
$body = @{
"defaults" = @{
"dueTime" = "22:00"
"addedStudentAction" = $True
"addToCalendarActionAsEnum" = "studentsOnly"
}
} | ConvertTo-Json
## /\ Change the settings here /\ ##
$classes | Foreach-Object -Begin { $progress = 0 } -Process {
$uri = "https://assignments.onenote.com/api/v1.0/edu/classes/$($_.id)/defaultsAndSettings"
Invoke-WebRequest -Uri $uri -Method Patch -Body $body -Headers $header -ContentType "application/json" -UseBasicParsing > $null
$progress++
Write-Progress -Activity "Updating teams settings" -Status "Teams updated: $progress out of $($classes.Count)" -PercentComplete (($progress / $classes.Count) * 100)
}
This script will take a while to run, but once it's done you can check the assignment settings in the class teams to make sure they've been changed correctly.
Edits you might want to make in your own deployment of the script
For larger deployments
- Store the teams ID's you set so when you run the script again it only updates the settings for new teams
- When adding to new teams, finding the list of total classes and the list of classes the user is already in and only adding the user to the new classes