๐ Recipe ยท SharePoint & OneDrive
Create a SharePoint Team Site via Microsoft Graph
Provision a new Microsoft 365 Group-backed SharePoint Team Site with a designated owner, using the Graph API, Admin Center, or PowerShell.
Complexity
Intermediate
Impact
Collaboration + Provisioning + SharePoint + Microsoft 365 Groups
Context
Why This Matters
SharePoint Team Sites are the backbone of departmental, project, and committee collaboration in Microsoft 365. Each Team Site is backed by a Microsoft 365 Group that controls membership, mailbox, calendar, Planner plan, and โ optionally โ a Microsoft Teams team. When IT is asked to "stand up a site for a team," the cleanest path is to create a Group-connected Team Site, because permissions, licensing, and lifecycle policies (retention, expiration, sensitivity labels) then flow through a single object.
Run this recipe when a business unit requests a new collaboration workspace, when provisioning a project site that needs owners and members from day one, or when scripting bulk site creation as part of onboarding a new department or acquisition.
Why the Graph API path?
Creating the Microsoft 365 Group via Graph (POST /groups with groupTypes: ["Unified"]) automatically provisions the SharePoint site at https://<tenant>.sharepoint.com/sites/<mailNickname>. This is faster, more reproducible, and avoids the inconsistent behavior of the classic /sites/add endpoint (which creates site-only, not Group-connected, sites).
Expected Outcomes
- A new Microsoft 365 Group named after the site, with a chosen primary owner.
- An automatically provisioned SharePoint Team Site reachable at
https://{tenant}.sharepoint.com/sites/{mailNickname}. - A default document library, OneNote notebook, Planner plan, and shared mailbox tied to the group.
- Site visibility set to Private (or Public) per the request.
- Audit trail of the creation event in the Microsoft 365 audit log and group creation activity.
Risks & Considerations
Gotchas & warnings
- Verify the owner exists first. Looking up the owner by UPN before creation prevents half-provisioned groups with no owner. A common mistake is assuming a domain (e.g.
@contoso.com) that doesn't match the tenant's actual verified domain. - Name collisions. Always
GET /groups?$filter=displayName eq '...'before creating. Duplicate display names are technically allowed but cause user confusion; duplicatemailNicknamevalues will fail outright. - mailNickname rules. Must be unique across the tenant, no spaces, limited special characters. Leading digits are allowed but some older clients render them poorly โ prefer alphabetic prefixes when possible.
- Group creation may be restricted. If your tenant has Group creation restricted to a specific security group (a common governance setting), the service principal or admin running this call must be in that group.
- Sensitivity labels & naming policies. If Azure AD group naming policy is enabled, your
displayNameandmailNicknamemay be auto-prefixed/suffixed. Confirm the resulting site URL after creation. - Provisioning delay. The SharePoint site can take 30โ120 seconds to fully provision after the group is created. Do not assume the site URL is immediately reachable.
- Deletion is soft. Deleting the group soft-deletes the site for 30 days. Don't create test sites in production without a cleanup plan.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| Group.ReadWrite.All | Required to create the Microsoft 365 Group that backs the Team Site. |
| User.Read.All | Required to resolve the site owner by UPN or display name before assigning ownership. |
| Directory.ReadWrite.All | Required when the tenant has group creation governance or when binding owners via @odata.bind. |
| Sites.FullControl.All | Optional โ needed only if you plan to immediately apply custom site-level configuration (templates, permissions, features) after creation. |
The fastest way to get this done: just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex Pro
For End Users
How an employee would ask Dex for help
Create a Team Site from the SharePoint Admin Center
This is the fastest path for a one-off request where an admin wants to review choices in a GUI.
Sign in to the SharePoint Admin Center at
https://{tenant}-admin.sharepoint.comas a SharePoint Administrator or Global Administrator.In the left navigation, go to:
Sites โ Active sites โ + Create
Choose Team site (the option that says "Collaborate on a project or topic with your team. Connects to Microsoft 365 Group"). Do not pick "Other options" unless you specifically need a classic site.
Fill in the site details:
- Site name: the display name (e.g.
Project Aurora). - Group email address: auto-populates from the site name. This becomes the
mailNicknameand the site URL slug โ review it carefully. - Site address: confirm the final URL, e.g.
https://{tenant}.sharepoint.com/sites/ProjectAurora. - Site description: one-line purpose statement.
- Privacy settings: Private (recommended) or Public.
- Language: cannot be changed later โ pick carefully.
- Site name: the display name (e.g.
Click Next. On the members screen, add the primary site owner (required) and any additional members. The owner is a group owner, not just a site collection admin.
Click Finish. Provisioning completes in 30โ120 seconds.
Verify the site exists by navigating to its URL and confirming the owner can access it with full control.
Create a Team Site via Microsoft Graph
The Graph approach creates a Microsoft 365 Group with groupTypes: ["Unified"], which automatically provisions the SharePoint Team Site.
Step 1 โ Resolve the owner's object ID
GET https://graph.microsoft.com/v1.0/users/{ownerUpn}?$select=id,displayName,userPrincipalNameIf the UPN lookup returns 404, fall back to a search:
GET https://graph.microsoft.com/v1.0/users?$filter=startswith(userPrincipalName,'{prefix}')&$select=id,displayName,userPrincipalNameStep 2 โ Check for display name collisions
GET https://graph.microsoft.com/v1.0/groups?$filter=displayName eq '{siteName}'&$select=id,displayNameExpect @odata.count: 0 and an empty value array before proceeding.
Step 3 โ Create the group (provisions the site)
POST https://graph.microsoft.com/v1.0/groups
Content-Type: application/json
{
"displayName": "Project Aurora",
"mailNickname": "ProjectAurora",
"description": "Cross-functional project collaboration site",
"groupTypes": ["Unified"],
"mailEnabled": true,
"securityEnabled": false,
"visibility": "Private",
"owners@odata.bind": [
"https://graph.microsoft.com/v1.0/users/{ownerObjectId}"
]
}Response (201 Created) returns the new group's id, mail, and other metadata. The SharePoint site is provisioned asynchronously.
Step 4 โ Retrieve the provisioned SharePoint site
Poll until the site responds (usually < 2 minutes):
GET https://graph.microsoft.com/v1.0/groups/{groupId}/sites/rootThe response includes webUrl, e.g. https://{tenant}.sharepoint.com/sites/ProjectAurora.
Step 5 (optional) โ Add additional owners or members
POST https://graph.microsoft.com/v1.0/groups/{groupId}/members/$ref
{ "@odata.id": "https://graph.microsoft.com/v1.0/users/{userId}" }Create a Team Site with PowerShell
Two production-ready options. Pick the one that matches your tooling.
Option A โ Microsoft Graph PowerShell SDK (recommended)
Works anywhere PowerShell 7+ runs. Uses the same Graph endpoints as the API recipe.
# Install once
Install-Module Microsoft.Graph -Scope CurrentUser
# Connect with the scopes needed to create groups and read users
Connect-MgGraph -Scopes "Group.ReadWrite.All","User.Read.All","Directory.ReadWrite.All"
# Resolve the owner by UPN
$owner = Get-MgUser -UserId "owner@contoso.com"
# Build the group payload (owners@odata.bind requires AdditionalProperties)
$params = @{
DisplayName = "Project Aurora"
MailNickname = "ProjectAurora"
Description = "Cross-functional project site"
GroupTypes = @("Unified")
MailEnabled = $true
SecurityEnabled = $false
Visibility = "Private"
AdditionalProperties = @{
"owners@odata.bind" = @("https://graph.microsoft.com/v1.0/users/$($owner.Id)")
}
}
$group = New-MgGroup -BodyParameter $params
Write-Host "Group created: $($group.Id)"
Option B โ SharePoint PnP PowerShell
Higher-level cmdlet if you already use PnP for site configuration:
Install-Module PnP.PowerShell -Scope CurrentUser
Connect-PnPOnline -Url "https://{tenant}-admin.sharepoint.com" -Interactive
New-PnPSite `
-Type TeamSite `
-Title "Project Aurora" `
-Alias "ProjectAurora" `
-Description "Cross-functional project site" `
-IsPublic:$false `
-Owner "owner@contoso.com"
PnP returns the new site URL directly. Under the hood it calls the same Graph endpoints.
Next steps