Provisionamento de classes em escala usando o PowerShell e o Microsoft Graph

À medida que a Microsoft melhora a sua postura de segurança em todos os produtos e serviços, houve alterações à funcionalidade da API que podem afetar os clientes que anteriormente dependiam de permissões apenas da aplicação para aprovisionar Blocos de Notas Escolares e Equipas Escolares através de APIs.

Nota

Na maioria dos casos, recomendamos a utilização do School Sincronização de Dados (SDS), um serviço gratuito que ajuda a automatizar o processo de sincronização dos dados do utilizador e da lista a partir de Sistemas de Gestão ou Informações de Estudantes com o Microsoft 365. O SDS ajuda-o a gerir a sua organização educativa, utilizadores, turmas e funções, sincronizando os seus dados com o Microsoft Entra ID e o Microsoft 365, para que possa utilizar o Microsoft Teams, Intune para Educação, Exchange Online, SharePoint Online, blocos de notas escolares do OneNote e ativar aplicações de terceiros com o Início de sessão único integração.

Ainda pode aprovisionar turmas e blocos de notas à escala com o PowerShell e o Microsoft Graph ao seguir os métodos suportados. Este artigo descreve os passos e fornece ligações para documentação relevante.

Importante

Se estiver a trabalhar com um parceiro externo no aprovisionamento em escala de turmas, partilhe este artigo com esse parceiro antes de tomar medidas por conta própria.

Provisionamento de novas classes

Aviso

Antes de 21 de agosto de 2025, uma versão anterior desta documentação recomendava o aprovisionamento através do PowerShell do Teams antes de as atualizações necessárias terem sido feitas. Estas atualizações estão agora concluídas e pode continuar com esta abordagem de momento. Obrigado pela sua paciência.

É simples aprovisionar novas turmas através do PowerShell do Teams, que incluirá toda a configuração necessária para turmas e blocos de notas. Basta personalizar o nome a apresentar pretendido no seguinte script e executá-lo como administrador.

Importante

O script seguinte exige que utilize a versão 7.3.1 ou posterior do PowerShell do Microsoft Teams . 

Script de exemplo

# Using the Teams PowerShell SDK
Install-Module -MicrosoftTeams -Force -AllowClobber
New-Team -DisplayName 'Test Class 20251208.4' -Template 'EDU_Class'

Opção 2: utilizar o Microsoft Graph PowerShell

Se não tiver acesso ao PowerShell do Teams, poderá querer explorar classes de aprovisionamento à escala através do Microsoft Graph. Edite os parâmetros na parte superior do script a seguir conforme apropriado e, em seguida, execute o script como administrador para provisionar classes e blocos de anotações em escala:

Script de exemplo

# Using the MS Graph API
Install-Module Microsoft.Graph -AllowClobber -Force

# PARAMETERS
$Name = "Test Class 20251208.3"
$Description = "A Test Class"
$Mail =  $Name -replace '[^a-zA-Z0-9\s]|[ ]', '' # Replace this mail alias with a preferred generation method
$OwnerId = "000-000-00000-000000-000" # Replace this with the Owner's GUID
# ------------

# Create a new M365 Group
$CreateGroupBody = @"
{
  "description": "$Name",
  "displayName": "$Description",
  "groupTypes": [
    "Unified"
  ],
  "mailEnabled": false,
  "mailNickname": "$Mail",
  "securityEnabled": false,
  "members@odata.bind": [
    "https://graph.microsoft.com/v1.0/users/$OwnerId"
  ], 
  "owners@odata.bind": [
    "https://graph.microsoft.com/v1.0/users/$OwnerId"
  ],
  "visibility": "HiddenMembership",
  "creationOptions": [
    "ExchangeProvisioningFlags:461",
    "classAssignments"
  ],
  "extension_fe2174665583431c953114ff7268b7b3_Education_ObjectType": "Section",
  "resourceBehaviorOptions": [
    "appRoleForSite:22d27567-b3f0-4dc2-9ec2-46ed368ba538:fullcontrol",
    "appRoleForSite:c9a559d2-7aab-4f13-a6ed-e7e9c52aec87:fullcontrol",
    "appRoleForSite:13291f5a-59ac-4c59-b0fa-d1632e8f3292:fullcontrol",
    "appRoleForSite:2d4d3d8e-2be3-4bef-9f87-7875a61c29de:fullcontrol",
    "appRoleForSite:8f348934-64be-4bb2-bc16-c54c96789f43:fullcontrol"
  ]
}
"@
$NewGroup = Invoke-MgGraphRequest -uri 'https://graph.microsoft.com/v1.0/groups/' -Body $CreateGroupBody -Method POST -ContentType "application/json"

# Create Teams Class Team from group
$CreateTeamBody = @{
    "template@odata.bind" = "https://graph.microsoft.com/v1.0/teamsTemplates('educationClass')"
    "group@odata.bind" = "https://graph.microsoft.com/v1.0/groups('$($NewGroup.Id)')"
}
New-MgTeam -BodyParameter $CreateTeamBody​​​​​​​

Resolução de problemas: conceder permissões a sites escolares existentes

Nota

Esta abordagem também requer que a pessoa que executa o script seja um administrador do site, conforme descrito aqui. O script abaixo inclui um passo para adicionar o utilizador com sessão iniciada como um administrador de site para os sites que necessitam de resolução de problemas.

Se já tiver turmas aprovisionadas e estiver a observar falhas ou problemas de permissão com o Blocos de Notas Escolares ou Atribuições do Teams, pode atualizar as permissões de site para as suas turmas através do seguinte script, ao substituir o parâmetro rawGroups pelos groupIDs das turmas afetadas:

Script de exemplo

#You will need to connect to SharePoint, Exchange Online, and Graph with the following -Scopes Sites.FullControl.All, as well as collect the groupIDs of Class Teams affected
$rawGroups =@("b0a5905d-09ae-4605-8e12-94da93ecbe92","e0eec729-24ef-451e-b079-56d0baf4dfc9")
# Convert to array of objects with .groupid
$groups = $rawGroups | ForEach-Object { Get-UnifiedGroup -Identity $_ }
$step = 0

#get the currently logged in user's account to add as a site admin
$CUA = (get-mgcontext).account


foreach ($group in $groups) {
 $step = $step + 1
 Set-SPOUser -Site $group.SharePointSiteUrl -LoginName $CUA -IsSiteCollectionAdmin $true
 Write-Host "SiteCollectionAdmin added on $step of $($Groups.Count) Class Sites"
}

#Pause for 5 minutes before triggering the General Folder creation
Write-Host "Pausing for 5 Minutes before adding perms to allow SiteCollectionAdmin to propagate"
Start-Sleep -Seconds 300

Write-Host "Working on $($Groups.Count) Classes"

foreach ($group in $groups) {
 #$step = $step + 1
 $Site = Get-MgGroupSite -GroupId $group.ExternalDirectoryObjectId -SiteId "root"
 $SiteId = $Site.Id
 Write-Host "Processing permissions on $step of $($Groups.Count) Classes"
 # These are the AppIds for common Microsoft EDU Apps
 $AppIds = @{
 "8f348934-64be-4bb2-bc16-c54c96789f43"="EDU Assignments";
 "22d27567-b3f0-4dc2-9ec2-46ed368ba538"="Reading Assignments";
 "2d4d3d8e-2be3-4bef-9f87-7875a61c29de"="OneNote";
 "c9a559d2-7aab-4f13-a6ed-e7e9c52aec87"="Microsoft Forms";
 "13291f5a-59ac-4c59-b0fa-d1632e8f3292"="EDU OneNote";
 }

# Apply the permissions to the group site
$AppIds.Keys | %{
  $AppId = $_
  $Name = $AppIds[$_]

  $Body = @"
  { 
      "roles": ["fullcontrol"], 
      "grantedToIdentities": [{ 
        "application": { 
          "id": "$AppId",
          "displayName": "$Name"
        }
      }] 
  }
"@

  Invoke-MgGraphRequest -Method POST -Uri "https://graph.microsoft.com/v1.0/sites/$SiteId/permissions" -Body $Body -ContentType "application/json"
}
}

Write-Host "Processed $($Groups.Count) Classes, removing sitecollectionadmin"
$step = 0
foreach ($group in $groups) {
 $step = $step + 1
 Set-SPOUser -Site $group.SharePointSiteUrl -LoginName $CUA -IsSiteCollectionAdmin $false
 Write-Host "SiteCollectionAdmin removed on $step of $($Groups.Count) Class Sites"
}