Consume the Graph API and create O365 groups/modern team sites with CSOM C#

In this post, we will talk about how to get the access token in CSOM C# and then talk to Graph.

From Interact with Graph and make O365 Groups with AzureFunctions PowerShell

What is the Trick?

The problem is to authenticate with Azure AD and get an access token that we can use to talk to the Office 365 Graph. The trick, is a little not-well known thing called Resource Owner grant.


I have a few links about the Resource Owner grant type at the end. Basically, this grant_type lets you use username/password to obtain an access token.

First of all we will setup Azure App registration.

We need the permission to Read and Write All groups (Group.ReadWrite.All).

If you are familiar with it, just skip ahead to the code section.

If not, you need to follow the below steps:

First of all, navigate to your Azure Portal site or Azure AD portal. You need to use the account which has access to the Azure AD.

Once logged in, go to the App registration page as below:

Azure Active Directory page > App registrations > New Application registration.


Inside that, enter your details by providing some name and a valid Sign-on URL. Keep the Application type as Web App / API. Then click on Create. See below screengrab :


Once the application is created, navigate to it.

Please copy the application ID. This will be our client Id.


Now, go to the required permission and click on Add.





Inside the delegated permissions, click on the Read and write all groups


Click the awesome Grant Permissions button at the top of the permissions registration, this grants it for users in your Active Directory.



You will need some clientsecrets – create them from Keys. I like them not expiring for a long time. So I pick the Never expires option. It’ll expire when I’m long gone.



Copy down your ClientSecret.

Also, copy the Application ID which will be you client Id.

Now, lets do some coding šŸ™‚

For this demo purposes, I am using a console application.

You will need the below Nuget packages:


We are going to make use to PnP Core’s UnifiedGroupsUtility.CreateUnifiedGroup method to create a Unified group.

We are also going to make a POST request to get the Graph API access token, for that we are going to make use of the

System.Net.Http's HttpClient.

First we will create a class named AuthenticationResponse to map the JSON response.

public class AuthenticationResponse
public string token_type { get; set; }
public string scope { get; set; }
public int expires_in { get; set; }
public int expires_on { get; set; }
public int not_before { get; set; }
public string resource { get; set; }
public string access_token { get; set; }
public string refresh_token { get; set; }
public string id_token { get; set; }

Now, in our main method, it will be as below:

class Program
static void Main(string[] args)
Task.Run(() => MainAsync());
static async Task MainAsync()
string userName = "";
string password = "password";
List<KeyValuePair<string, string>> vals = new List<KeyValuePair<string, string>>();
string tenantName = "";
string authString = "" + tenantName;
string resource = "";
AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);
string clientId = "<client-id>";
string key = "<client-secret>";
vals.Add(new KeyValuePair<string, string>("client_id", clientId));
vals.Add(new KeyValuePair<string, string>("resource", resource));
vals.Add(new KeyValuePair<string, string>("username", userName));
vals.Add(new KeyValuePair<string, string>("password", password));
vals.Add(new KeyValuePair<string, string>("grant_type", "password"));
vals.Add(new KeyValuePair<string, string>("client_secret", key));
string url = string.Format("{0}/oauth2/token", tenantName);
using (HttpClient httpClient = new HttpClient())
httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
HttpContent content = new FormUrlEncodedContent(vals);
HttpResponseMessage hrm = httpClient.PostAsync(url, content).Result;
AuthenticationResponse authenticationResponse = null;
if (hrm.IsSuccessStatusCode)
Stream data = await hrm.Content.ReadAsStreamAsync();
DataContractJsonSerializer serializer = new
authenticationResponse = (AuthenticationResponse)serializer.ReadObject(data);
var accessToken = authenticationResponse.access_token;
Stream groupLogoStream = new FileStream("C:\\groupassets\\logo-original.png",
FileMode.Open, FileAccess.Read);
var group = UnifiedGroupsUtility.CreateUnifiedGroup("displayName", "description",
"MyModernTeamSite", accessToken, groupLogo: groupLogoStream);
string groupUrl = group.SiteUrl;
string groupId = group.GroupId;
// Get all groups in the tenant
//List<UnifiedGroupEntity> groups = UnifiedGroupsUtility.ListUnifiedGroups(accessToken);
// Update description and group logo programatically
//groupLogoStream = new FileStream("C:\\groupassets\\logo-new.png", FileMode.Open, FileAccess.Read);
//UnifiedGroupsUtility.UpdateUnifiedGroup(groupId, accessToken, description: "Updated description", groupLogo: groupLogoStream);
// Delete group programatically
//UnifiedGroupsUtility.DeleteUnifiedGroup(groupId, accessToken);

Done. This will create a Modern Unified team site with Office 365 group enabled.

References – Provisioning a “modern” team site programmatically

Interact with Graph and make O365 Groups with AzureFunctions PowerShell

9 thoughts on “Consume the Graph API and create O365 groups/modern team sites with CSOM C#

  1. Hi, I need to update the existing modern site office 365 group name using csom so that updated group name will be visible on modern team site collection home page, Could you please help me for the same?


      1. Though I have one question!
        Can we add association of hub site in this method? I don’t see any extra property for that but if you can just help me get the method name to use to associate hub site to it. I really appreciate it.


  2. This is exactly what I have been searching for. I am new to the graph API and azure app registration. I knew the PNP API existed, but didn’t know how to create the access token. Thank you for your post. I will give this a try and post back on progress!

    Liked by 1 person

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.