Create O365 Group and Team using Graph API

I would like to share the procedure to create a Microsoft 365 Group and a team in teams using Graph API. We will use application (AD App) permisions instead of current user (Delegate) permissions.

Create Group Reference:
https://docs.microsoft.com/en-us/graph/api/group-post-groups?view=graph-rest-1.0&tabs=http

Create Team Reference:
https://docs.microsoft.com/en-us/graph/api/team-put-teams?view=graph-rest-1.0&tabs=http 

Steps to create Daemon App:

  1. Create App in Azure Active Directory
  2. Provide following application Graph API permissions.
    • Groups.ReadWrite.All, Directory.ReadWrite.All, Team.Create
  3. Grant Admin Consent.


I have used Azure serverless Function App technology because it allows developers to host business logic that can be executed without managing or provisioning infrastructure.

I have created a Http trigger function to create Group using Graph API. I have chosen .Net Framework to write C# code.

Create Group Code:


I have created another Http trigger function to create a team from the above created group.

Create Team Code:


I have used MSAL.Net library to authenticate and consume Graph API. We have to install following Nuget package to get this library.


The following code will connect to AD app and get the access token. Using this access token, we can consume Graph API.

string clientId = Environment.GetEnvironmentVariable("AD_AppId");
string tenantId = Environment.GetEnvironmentVariable("AD_Tenant");
string clientSecret = Environment.GetEnvironmentVariable("AD_AppSecret");
                        
IConfidentialClientApplication daemonApp = ConfidentialClientApplicationBuilder
                                                     .Create(clientId)
                                                     .WithTenantId(tenantId)
                                                     .WithClientSecret(clientSecret)
                                                     .Build();
AuthenticationResult result;
try
{
    result = await daemonApp.AcquireTokenForClient(new[] { MSGraphScope }).ExecuteAsync();
}
catch (MsalServiceException ex) when (ex.Message.Contains("AADSTS70011"))
{
    log.Error("Scope provided is not supported");
    // Invalid scope. The scope has to be of the form "https://resourceurl/.default"
    // Mitigation: change the scope to be as expected
    return req.CreateResponse(HttpStatusCode.BadRequest, "Scope provided is not supported");
}

For demo purpose, I have stored required app settings in the Azure Function App application settings otherwise Microsoft higly recommends to use Azure Key Vault.

Also, I am connecting to the app using ClientSecret but for production applications it is highly recommended to use Certificate.

How am I calling these Http trigger azure functions? The answer is Power Automate.

I have used HTTP premium action to invoke azure functions from Power Automate as below.






If the group was created less than 15 minutes ago, it's possible for the Create team call to fail with a 404 error code due to replication delays. The recommended pattern is to retry the Create team call three times, with a 10 second delay between calls.

Thanks to Power Automate HTTP action retry policy. We don't have to write any special logic. The Power Automate applies retry policy to HTTP status codes 408,429 and 5xx in addition to any connectivity exceptions. Due to this if any exception occurs, I am returning 500 error intentionally so that Power Automate can retry again.

Thanks for reading this.

Comments

Popular posts from this blog

Switch from Classic to Claims Authentication in SharePoint 2010

How to query list data using web service