Microsoft Tech Community Live:  Microsoft Teams Edition
November 09, 2021, 08:00 AM - 12:00 PM (PST)
SOLVED

Team Creation with Graph API not creating SharePoint site

%3CLINGO-SUB%20id%3D%22lingo-sub-2037775%22%20slang%3D%22en-US%22%3ETeam%20Creation%20with%20Graph%20API%20not%20creating%20SharePoint%20site%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2037775%22%20slang%3D%22en-US%22%3E%3CP%3EHi%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20am%20using%20Powershell%20%2F%20GraphAPI%20to%20create%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EA%20M365%20Dynamic%20Group%3C%2FP%3E%3CP%3EThen%20a%20Team%20based%20on%20this%20Group%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20issue%20i%20have%20is%20both%20are%20created%20as%20expected%2C%20but%20I%20never%20get%20a%20Sharepoint%20Group%20Link%20on%20the%20M365%20Group%2C%20and%20therefore%20no%20Sharepoint%20back%20end%20from%20the%20Team.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20am%20using%20a%20Service%20Principle%20in%20Azure%2C%20with%20the%20below%20Application%20API%20permission%20to%20GraphAPI%3C%2FP%3E%3CDIV%20class%3D%22mceNonEditable%20lia-copypaste-placeholder%22%3E%26nbsp%3B%3C%2FDIV%3E%3CP%3EDirectory.ReadAll%3C%2FP%3E%3CP%3EGroup.ReadWrite.Al%3C%2FP%3E%3CP%3EUser.Read%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAny%20help%20appreciated%20-%20i%20can%20get%20this%20to%20work%20ok%20if%20im%20just%20using%20some%20powershell%20cmdlets%20to%20cerate%20the%20groups%20and%20Teams%20-%20but%20there%20are%20issues%20with%20using%20the%20MicrosofTeams%20cmdlets%20with%20the%20applicationid%20(on%20version%201.1.9%20anyway).%20Besides%20i%20was%20hoping%20GraphAPI%20would%20be%20a%20smoother%20way%20of%20doing%20this!%3C%2FP%3E%3CDIV%20class%3D%22mceNonEditable%20lia-copypaste-placeholder%22%3E%26nbsp%3B%3C%2FDIV%3E%3CP%3EAre%20there%20other%20permissions%20I%20need%20from%20the%20Service%20Principle%20for%20Teams%20to%20create%20the%20SharePoint%20site%3F%20I%20seriously%20cant%20see%20any%20other%20options.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EBelow%20is%20the%20Group%20missing%20the%20Sharepoint%20Link.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22FireDog_0-1609964825398.png%22%20style%3D%22width%3A%20263px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F244606iBC7FC310DAAC8710%2Fimage-dimensions%2F263x126%3Fv%3D1.0%22%20width%3D%22263%22%20height%3D%22126%22%20role%3D%22button%22%20title%3D%22FireDog_0-1609964825398.png%22%20alt%3D%22FireDog_0-1609964825398.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CDIV%20class%3D%22mceNonEditable%20lia-copypaste-placeholder%22%3E%26nbsp%3B%3C%2FDIV%3E%3CP%3E%3CSTRONG%3EThis%20is%20the%20code%20to%20create%20the%20M365%20Group%26nbsp%3B%3C%2FSTRONG%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%23Prepare%20generic%20OAuth%20Bearer%20token%20header%3CBR%20%2F%3E%24headers%20%3D%20%40%7B%3CBR%20%2F%3E%22Content-Type%22%20%3D%20%22application%2Fjson%22%3CBR%20%2F%3EAuthorization%20%3D%20%22Bearer%20%24accessToken%22%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%3CBR%20%2F%3E%23Create%20the%20Office%20365%20Group%20-%20Post%20Request%3CBR%20%2F%3E%24NewGroup%20%3D%20%40%7B%3CBR%20%2F%3EDescription%20%3D%20%22MyTeam%22%3CBR%20%2F%3E%22owners%40odata.bind%22%20%3D%20%40(%22%3CA%20href%3D%22https%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fusers%2F4591ef05-c38a-40eb-82c6-91db038a5f4f%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fusers%2F4591ef05-c38a-40eb-82c6-91db038a5f4f%3C%2FA%3E%22)%3CBR%20%2F%3EDisplayName%20%3D%20%22MyTeam%22%3CBR%20%2F%3EgroupTypes%20%3D%20%40(%22Unified%22%2C%22DynamicMembership%22)%3CBR%20%2F%3EmembershipRule%20%3D%20%22(user.userPrincipalName%20-Contains%20%60%22USERNAMEHERE%60%22)%22%3CBR%20%2F%3EmembershipRuleProcessingState%20%3D%20%22On%22%3CBR%20%2F%3EmailEnabled%20%3D%20%24false%3CBR%20%2F%3EmailNickname%20%3D%20%22myTeam%22%3CBR%20%2F%3Esecurityenabled%20%3D%20%24false%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%24creategroupbody%20%3D%20ConvertTO-Json%20-InputObject%20%24NewGroup%3CBR%20%2F%3E%24response%20%3D%20Invoke-RestMethod%20-Uri%20%22%3CA%20href%3D%22https%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fgroups%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fgroups%3C%2FA%3E%22%20-Body%20%24creategroupbody%20-Method%20Post%20-Headers%20%24headers%20-UseBasicParsing%3CBR%20%2F%3E%24groupid%20%3D%20%24response.id%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CSTRONG%3E...%20and%20this%20creates%20my%20team%3C%2FSTRONG%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%24teamBody%20%3D%3CBR%20%2F%3E'%7B%3CBR%20%2F%3E%22memberSettings%22%3A%20%7B%3CBR%20%2F%3E%22allowCreateUpdateChannels%22%3A%20true%2C%3CBR%20%2F%3E%22allowDeleteChannels%22%3A%20true%2C%3CBR%20%2F%3E%22allowAddRemoveApps%22%3A%20true%2C%3CBR%20%2F%3E%22allowCreateUpdateRemoveTabs%22%3A%20true%2C%3CBR%20%2F%3E%22allowCreateUpdateRemoveConnectors%22%3A%20true%3CBR%20%2F%3E%7D%2C%3CBR%20%2F%3E%22guestSettings%22%3A%20%7B%3CBR%20%2F%3E%22allowCreateUpdateChannels%22%3A%20true%2C%3CBR%20%2F%3E%22allowDeleteChannels%22%3A%20true%3CBR%20%2F%3E%7D%2C%3CBR%20%2F%3E%22messagingSettings%22%3A%20%7B%3CBR%20%2F%3E%22allowUserEditMessages%22%3A%20true%2C%3CBR%20%2F%3E%22allowUserDeleteMessages%22%3A%20true%2C%3CBR%20%2F%3E%22allowOwnerDeleteMessages%22%3A%20true%2C%3CBR%20%2F%3E%22allowTeamMentions%22%3A%20true%2C%3CBR%20%2F%3E%22allowChannelMentions%22%3A%20true%3CBR%20%2F%3E%7D%2C%3CBR%20%2F%3E%22funSettings%22%3A%20%7B%3CBR%20%2F%3E%22allowGiphy%22%3A%20true%2C%3CBR%20%2F%3E%22giphyContentRating%22%3A%20%22strict%22%2C%3CBR%20%2F%3E%22allowStickersAndMemes%22%3A%20true%2C%3CBR%20%2F%3E%22allowCustomMemes%22%3A%20true%3CBR%20%2F%3E%7D%3CBR%20%2F%3E%7D'%3C%2FP%3E%3CP%3E%24newTeam%20%3D%20Invoke-RestMethod%20-Uri%20%22%3CA%20href%3D%22https%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fgroups%2F%24(%24Groupid)%2Fteam%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fgroups%2F%24(%24Groupid)%2Fteam%3C%2FA%3E%22%20-Method%20PUT%20-Headers%20%24headers%20-Body%20%24teamBody%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20grab%20my%20bearer%20token%20with%20further%20code%20-%20thats%20working%20fine%2C%20i%20get%20the%20token%20to%20do%20run%20the%20above.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%24env%3AgraphApiDemoAppId%20%3D%20%22xx%22%20%23%20HIDDEN%3CBR%20%2F%3E%24env%3AgraphApiDemoAppSecret%20%3D%20%22xx%22%20%23%20HIDDEN%3CBR%20%2F%3E%24env%3AtenantId%20%3D%20%22xx%22%20%23%20HIDDEN%3C%2FP%3E%3CP%3E%24oauthUri%20%3D%20%22%3CA%20href%3D%22https%3A%2F%2Flogin.microsoftonline.com%2F%24env%3AtenantId%2Foauth2%2Fv2.0%2Ftoken%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3Ehttps%3A%2F%2Flogin.microsoftonline.com%2F%24env%3AtenantId%2Foauth2%2Fv2.0%2Ftoken%3C%2FA%3E%22%3C%2FP%3E%3CP%3E%23%20Create%20token%20request%20body%3CBR%20%2F%3E%24tokenBody%20%3D%20%40%7B%3CBR%20%2F%3Eclient_id%20%3D%20%24env%3AgraphApiDemoAppId%3CBR%20%2F%3Eclient_secret%20%3D%20%24env%3AgraphApiDemoAppSecret%3CBR%20%2F%3Escope%20%3D%20%22%3CA%20href%3D%22https%3A%2F%2Fgraph.microsoft.com%2F.default%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgraph.microsoft.com%2F.default%3C%2FA%3E%22%3CBR%20%2F%3Egrant_type%20%3D%20%22client_credentials%22%3CBR%20%2F%3E%7D%3C%2FP%3E%3CP%3E%23%20Retrieve%20access%20token%3CBR%20%2F%3E%24tokenRequest%20%3D%20Invoke-RestMethod%20-Uri%20%24oauthUri%20-Method%20POST%20-ContentType%20%22application%2Fx-www-form-urlencoded%22%20-Body%20%24tokenBody%20-UseBasicParsing%3C%2FP%3E%3CP%3E%23%20Save%20access%20token%3CBR%20%2F%3E%24accessToken%20%3D%20(%24tokenRequest).access_token%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ECheers%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIan%20Fraser%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-2037775%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EDeveloper%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ETeams%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2091935%22%20slang%3D%22en-US%22%3ERe%3A%20Team%20Creation%20with%20Graph%20API%20not%20creating%20SharePoint%20site%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2091935%22%20slang%3D%22en-US%22%3EIt%20is%20not%20about%20permissions%2C%20but%20the%20fact%20that%20the%20SharePoint%20folders%20are%20created%20later%20in%20the%20provisioning.%20The%20fastest%20way%20to%20create%20them%20is%20to%20go%20ahead%20and%20click%20on%20Files%20tab%20in%20the%20created%20channel.%3CBR%20%2F%3E%3CBR%20%2F%3EHowever%20you%20can%20do%20a%20workaround%3CBR%20%2F%3E-%20after%20team%20creation%3CBR%20%2F%3E-%20retrieve%20the%20SharePoint%20Site%20information%20connected%20to%20the%20team%3CBR%20%2F%3E-%20retrieve%20the%20document%20library%20info%20(drive%20info%3A%20%24targetDriveIDURI%20%3D%20%22%3CA%20href%3D%22https%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fgroups%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fgroups%2F%3C%2FA%3E%22%20%2B%20%24teamID%20%2B%20%22%2Fdrive%22%20)%3CBR%20%2F%3E-%20knowing%20you%20channel%20name%20create%20a%20dummy%20file%20in%20the%20channel%20(yes%2C%20the%20channel%20folder%20doesn't%20exist%20but%20it%20is%20created%20during%20this%20process)%3CBR%20%2F%3E%20%24createfileURI%20%3D%20%22%3CA%20href%3D%22https%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fdrives%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgraph.microsoft.com%2Fv1.0%2Fdrives%2F%3C%2FA%3E%22%20%2B%20%24targetDriveID%20%2B%22%2Froot%3A%2F%22%20%2B%20%24channel.displayName%20%2B%22%2Fdummy_remove.txt%3A%2Fcontent%22%3CBR%20%2F%3E%20%24fileResponse%20%3D%20Invoke-RestMethod%20-Method%20Put%20-Uri%20%24createfileURI%20-Headers%20%40%7B%22Authorization%22%3D%22Bearer%20%24accessToken%22%7D%20-Body%20%24createfileContent%20-ContentType%20%22text%2Fplain%22%3CBR%20%2F%3E%3CBR%20%2F%3EAfter%20that%20you%20have%20the%20folder%20available%20for%20further%20use.%3CBR%20%2F%3E%3CBR%20%2F%3ENote%3A%20this%20doesn't%20work%20in%20Private%20channels.%20For%20those%20there%20is%20a%20need%20to%20wait%20or%20click%20in%20the%20UI.%3C%2FLINGO-BODY%3E
New Contributor

Hi

 

I am using Powershell / GraphAPI to create:

 

A M365 Dynamic Group

Then a Team based on this Group

 

The issue i have is both are created as expected, but I never get a Sharepoint Group Link on the M365 Group, and therefore no Sharepoint back end from the Team.

 

I am using a Service Principle in Azure, with the below Application API permission to GraphAPI

 

Directory.ReadAll

Group.ReadWrite.Al

User.Read

 

Any help appreciated - i can get this to work ok if im just using some powershell cmdlets to cerate the groups and Teams - but there are issues with using the MicrosofTeams cmdlets with the applicationid (on version 1.1.9 anyway). Besides i was hoping GraphAPI would be a smoother way of doing this!

 

Are there other permissions I need from the Service Principle for Teams to create the SharePoint site? I seriously cant see any other options.

 

Below is the Group missing the Sharepoint Link.

 

FireDog_0-1609964825398.png

 

This is the code to create the M365 Group 

 

#Prepare generic OAuth Bearer token header
$headers = @{
"Content-Type" = "application/json"
Authorization = "Bearer $accessToken"
}

#Create the Office 365 Group - Post Request
$NewGroup = @{
Description = "MyTeam"
"owners@odata.bind" = @("https://graph.microsoft.com/v1.0/users/4591ef05-c38a-40eb-82c6-91db038a5f4f")
DisplayName = "MyTeam"
groupTypes = @("Unified","DynamicMembership")
membershipRule = "(user.userPrincipalName -Contains `"USERNAMEHERE`")"
membershipRuleProcessingState = "On"
mailEnabled = $false
mailNickname = "myTeam"
securityenabled = $false
}
$creategroupbody = ConvertTO-Json -InputObject $NewGroup
$response = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/groups" -Body $creategroupbody -Method Post -Headers $headers -UseBasicParsing
$groupid = $response.id

 

 

... and this creates my team

 

$teamBody =
'{
"memberSettings": {
"allowCreateUpdateChannels": true,
"allowDeleteChannels": true,
"allowAddRemoveApps": true,
"allowCreateUpdateRemoveTabs": true,
"allowCreateUpdateRemoveConnectors": true
},
"guestSettings": {
"allowCreateUpdateChannels": true,
"allowDeleteChannels": true
},
"messagingSettings": {
"allowUserEditMessages": true,
"allowUserDeleteMessages": true,
"allowOwnerDeleteMessages": true,
"allowTeamMentions": true,
"allowChannelMentions": true
},
"funSettings": {
"allowGiphy": true,
"giphyContentRating": "strict",
"allowStickersAndMemes": true,
"allowCustomMemes": true
}
}'

$newTeam = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/groups/$($Groupid)/team" -Method PUT -Headers $headers -Body $teamBody

 

I grab my bearer token with further code - thats working fine, i get the token to do run the above.

 

$env:graphApiDemoAppId = "xx" # HIDDEN
$env:graphApiDemoAppSecret = "xx" # HIDDEN
$env:tenantId = "xx" # HIDDEN

$oauthUri = "https://login.microsoftonline.com/$env:tenantId/oauth2/v2.0/token"

# Create token request body
$tokenBody = @{
client_id = $env:graphApiDemoAppId
client_secret = $env:graphApiDemoAppSecret
scope = "https://graph.microsoft.com/.default"
grant_type = "client_credentials"
}

# Retrieve access token
$tokenRequest = Invoke-RestMethod -Uri $oauthUri -Method POST -ContentType "application/x-www-form-urlencoded" -Body $tokenBody -UseBasicParsing

# Save access token
$accessToken = ($tokenRequest).access_token

 

 

Cheers

 

Ian Fraser

 

3 Replies
It is not about permissions, but the fact that the SharePoint folders are created later in the provisioning. The fastest way to create them is to go ahead and click on Files tab in the created channel.

However you can do a workaround
- after team creation
- retrieve the SharePoint Site information connected to the team
- retrieve the document library info (drive info: $targetDriveIDURI = "https://graph.microsoft.com/v1.0/groups/" + $teamID + "/drive" )
- knowing you channel name create a dummy file in the channel (yes, the channel folder doesn't exist but it is created during this process)
$createfileURI = "https://graph.microsoft.com/v1.0/drives/" + $targetDriveID +"/root:/" + $channel.displayName +"/dummy_remove.txt:/content"
$fileResponse = Invoke-RestMethod -Method Put -Uri $createfileURI -Headers @{"Authorization"="Bearer $accessToken"} -Body $createfileContent -ContentType "text/plain"

After that you have the folder available for further use.

Note: this doesn't work in Private channels. For those there is a need to wait or click in the UI.
I was getting a similar issue, but mine where not Dynamic Groups. Read in an article that there was some idiosyncrasies between the teams client and the graph api. Turns out that the graph api for creating groups does not add "owners" to "direct members" so that when the owners access the team/site the site creation is failing as they are not added as members of the site correctly. By having the "owners" in the group "members" list when calling the API for Group it seemed to fix the issue for me.
best response confirmed by ThereseSolimeno (Microsoft)
Solution

@Shane_Blake Hi - thanks for reply. I actually raised a PS call in the end, and it turned out to be a problem that Microsoft had to fix at the back end - related to creating the SharePoint site on the time. I think it was a timing issue.

 

It wasnt fixed as part of my call, sounds like it was being fixed anyway.

 

I did read about the direct members - i add them now as part of my code anyway so we dont have just an owner without being a member. But it doesnt seem to effect anything for me if they are just owners - the site creation is all via Graph anyway so it doesnt care. 

 

Im using AD groups (on prem) and have a sync framework to manage membership - it fits in with our onboarding processes so we can assign Teams to departments / functions using AD Attributes, and the AD groups add 'exceptions' ie someone from department A wants to join the department B team, we drop them in the Exceptions AD group for the Department B team and the script does the rest. Ideal for Service Desk / integration into a JLT process. Decided to avoid cmdlets and do purely RESTAPI as ive hit so many issues with bugs.

 

Cheers