Seems creating Microsoft 365/O365 Group via CSOM not working. If you try to use SharePoint Client Side Object Model(CSOM) you might run into following exception:
Microsoft.SharePoint.Client.ServerException
HResult=0x80131500
Message=The web template GROUP#0 is not available for sites on this tenant.
Source=Microsoft.SharePoint.Client.Runtime
StackTrace:
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream)
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()
at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb)
at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()
We have to use Graph API and this sample should help get started. ROPC authentication is used. Delegated authentication should also work but not tested.
Setup Steps:
1] Setup Native App in AAD.
2] Copy the App Id as you will need to provide it later in the code.
3] Provide following Delegated Graph API permissions.
Groups.ReadWite.All, Directory.ReadWrite.All, openid, Team.Create, User.Read
4] Grant Admin consent.
5] See screenshot below:
6] Sample C# code to Create Microsoft 365/O365 Group with Teams:
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text;
namespace CreateGroupMultiGeo
{
class Program
{
static async Task Main(string[] args)
{
string clientId = "50168119-04dd-0000-0000-000000000000";
string email = "someuser@spotenant.onmicrosoft.com";
string passwordStr = "password";
var req = new HttpRequestMessage(HttpMethod.Post, "https://login.microsoftonline.com/bc8dcd4c-0d60-0000-0000-000000000000/oauth2/token")
{
Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["resource"] = "https://graph.microsoft.com",
["grant_type"] = "password",
["client_id"] = clientId,
["username"] = email,
["password"] = passwordStr,
["scope"] = "openid"
})
};
HttpClient httpClient = new HttpClient();
var res = await httpClient.SendAsync(req);
string json = await res.Content.ReadAsStringAsync();
if (!res.IsSuccessStatusCode)
{
throw new Exception("Failed to acquire token: " + json);
}
var result = (JObject)JsonConvert.DeserializeObject(json);
//create a group
HttpClient httpClientGroup = new HttpClient();
httpClientGroup.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.Value<string>("access_token"));
// Create a string variable and get user input from the keyboard and store it in the variable
string grpName = "MultiGeoGraphAPIGrp1";
string contentGroup = @"{
'displayName': '" + grpName + @"',"
+ @"'groupTypes': ['Unified'],
'mailEnabled': true,
'mailNickname': '" + grpName + @"',"
+ @"'securityEnabled': false,
'visibility':'Public',
'preferredDataLocation':'GBR',
'owners@odata.bind': ['https://graph.microsoft.com/v1.0/users/ecc0fc81-244b-0000-0000-000000000000']
}";
var httpContentGroup = new StringContent(contentGroup, Encoding.GetEncoding("utf-8"), "application/json");
var responseGroup = httpClientGroup.PostAsync("https://graph.microsoft.com/v1.0/groups", httpContentGroup).Result;
var content = await responseGroup.Content.ReadAsStringAsync();
dynamic grp = JsonConvert.DeserializeObject<object>(content);
Console.WriteLine(responseGroup.Content.ReadAsStringAsync().Result);
System.Threading.Thread.Sleep(3000);
//create a Team
HttpClient httpClientTeam = new HttpClient();
httpClientTeam.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.Value<string>("access_token"));
//create a team
string contentTeam = @"{
'memberSettings': {
'allowCreateUpdateChannels': true
},
'messagingSettings': {
'allowUserEditMessages': true,
'allowUserDeleteMessages': true
},
'funSettings': {
'allowGiphy': true,
'giphyContentRating': 'strict'
}
}";
var httpContentTeam = new StringContent(contentTeam, Encoding.GetEncoding("utf-8"), "application/json");
////Refere: https://docs.microsoft.com/en-us/graph/api/team-put-teams?view=graph-rest-1.0&tabs=http
var responseTeam = httpClientTeam.PutAsync(@"https://graph.microsoft.com/v1.0/groups/" + grp.id + @"/team", httpContentTeam).Result;
Console.WriteLine(responseTeam.Content.ReadAsStringAsync().Result);
Console.ReadKey();
}
}
}
Welcome to the SharePoint Blog! Learn best practices, news, and trends directly from the SharePoint team.