How to Completely Disable External Sharing for a Single Office 365 Group
Last updated on September 3, 2023
The Office 365 external sharing settings have been a hot topic in many conversations lately. I have also got to work with those, and in this blog post, I’ll tell you how to programmatically disable external sharing for a single Office 365 Group and its SharePoint site.
Disabling External Sharing for an Office 365 Group
To disable external sharing for a unified group, you need to add a setting template called Group.Unified.Guest to the group settings with “AllowToAddGuests” value set to false. There are two ways to add this setting template to an Office 365 Group: a PowerShell script or a request to Microsoft Graph API.
In both cases it can take a few minutes for the setting to be applied, so be patient when checking the result. The template id is the same across all tenants.
In case you want to see all the available templates, you can e.g. go to Graph Explorer and make a GET request to https://graph.microsoft.com/v1.0/groupSettingTemplates (you simply need to paste that url to the query field and hit Run Query, nothing else).
PowerShell
Here you first need to provide the tenant id for connecting to Azure AD and the id of the group you want to restrict access for. After that, when you run the script, you’ll be prompted for credentials to authenticate to both Exchange and Azure AD. After successful authentication, a new setting template is created with the AllowToAddGuest value set to false, and the template is applied to the group. The last line of code is commented out because the change doesn’t come into effect immediately, but you can run the line separately after a few minutes to ensure that the setting has been applied.
$tenantId = "tenant-guid-here" $groupId = "group-guid-here" # Connect to Exchange and Azure AD $cred = Get-Credential $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $cred -Authentication Basic -AllowRedirection Import-PSSession $session Connect-AzureAD -TenantId $tenantId -Credential $cred $template = Get-AzureADDirectorySettingTemplate -Id 08d542b9-071f-4e16-94b0-74abb372e3d9 $setting = $template.CreateDirectorySetting() $setting["AllowToAddGuests"] = $false New-AzureADObjectSetting -TargetType Groups -TargetObjectId $groupId -DirectorySetting $setting # You can use this line to check if the setting has been successfully applied after a little while # Get-UnifiedGroup -Identity $groupId | select Alias, AllowAddGuests
REST call to Graph API (C#)
Here we first create the request body, which is the setting template, and then make a POST request to Graph API. To keep this example simple enough, I’ll leave fetching the group id and access token to you.
public void AllowToAddGuests(string groupId, bool allow, string accessToken) { try { var body = $"{{'displayName': 'Group.Unified.Guest', 'templateId': '08d542b9-071f-4e16-94b0-74abb372e3d9', 'values': [{{'name': 'AllowToAddGuests','value': '{allow}'}}] }}"; GetRequest($"https://graph.microsoft.com/v1.0/groups/{groupId}/settings", "POST", new WebHeaderCollection { { "Authorization", "Bearer " + accessToken } }, body).GetResponse(); } catch (Exception e) { Console.WriteLine($"Could not adjust group external sharing settings: {e.Message}"); } } // A generic method you can use for constructing web requests public HttpWebRequest GetRequest(string url, string method, WebHeaderCollection headers, string body = null, string contentType = "application/json") { var request = (HttpWebRequest)WebRequest.Create(url); request.Method = method; request.Headers = headers; if (body != null) { var bytes = Encoding.UTF8.GetBytes(body); request.ContentLength = bytes.Length; request.ContentType = contentType; var stream = request.GetRequestStream(); stream.Write(bytes, 0, bytes.Length); stream.Close(); } return request; }
Now no one can invite external users to the group. This ensures that only internal users will have access to the group content, including for example Planner plans and Teams channels. There is still one exception though: the SharePoint site of the group.
Disabling external sharing on the SharePoint Site
Even though external users can no longer be added to group members, they can still be given access to the SharePoint site of the group via site permissions. This needs to be restricted separately. There are three ways to disable external sharing for modern Team Sites: PowerShell, CSOM, and SharePoint Site Templates. I’ll now show you how you can disable external sharing using PowerShell and CSOM. If you rather used Site Templates, read my Ultimate Guide to SharePoint Site Templates and Site Scripts – it contains all the information you need.
PowerShell
Here you first need to provide the admin site URL used for connecting to SharePoint, and the URL of the team site you want to restrict access for. After that, when you run the script, you’ll be prompted for credentials to authenticate. After successful authentication, access to the team site is restricted, and the new setting is printed in the console.
$adminSiteUrl = "https://mytenant-admin.sharepoint.com" $siteUrl = "https://mytenant.sharepoint.com/sites/team-site-url" $cred = Get-Credential Connect-SPOService $adminSiteUrl -Credential $cred Set-SPOSite -Identity $siteUrl -SharingCapability Disabled Get-SPOSite -Identity $siteUrl | select Url, SharingCapability
CSOM
Here we first create a client context using the admin site URL in order to get the Tenant object. As you can see, there is a small method for getting that admin site URL based on the site URL that has been provided as a parameter. Because there are so many ways to authenticate, I’ll leave creating the actual client context object to you.
After the tenant object is created, we can access site properties with the site URL, and set the sharing capability to disabled. Then all we need to do is to execute an update for the site properties for the change to come into effect.
public static void DisableSharingCapabilities(string siteUrl) { using (var ctx = GetClientContext(GetAdminSiteUrl(siteUrl))) { var tenant = new Tenant(ctx); var siteProperties = tenant.GetSitePropertiesByUrl(siteUrl, true); siteProperties.SharingCapability = SharingCapabilities.Disabled; siteProperties.Update(); ctx.ExecuteQuery(); } } public static string GetAdminSiteUrl(string url) { const string suffix = ".sharepoint.com"; var index = url.IndexOf(suffix, StringComparison.OrdinalIgnoreCase); url = url.Substring(0, index + suffix.Length); return url.Insert(index, "-admin"); } public static ClientContext GetClientContext(string url) { // Create a client context using your preferred authentication method }
Now external sharing is completely disabled for the whole Group, including its SharePoint site.
I hope this article was useful to you, and if you have any questions or comments, please leave them in the comments section below. Until next time!
HI Laura,
Thanks for posting these scripts and ideas.
I know this one is a few years old but, just wondering if you might show how to clean up existing sharing links.
I previously (prior to Sep. 9,2024) had a PowerShell running pnp comandlets to do this but, things changed in Microsoft land that affected authenticate through the script.
I have messed around with Azure enterprise apps but not getting any where fast.
When using Connect-SPOService and Get-SPOSiteGroup displays existing limited access groups and sharing links, (these are what I want to clean up using a script so all that remains are the security groups for the site.
The sharing links are displayed in my script as SharingLinks.xxxxx-unknown-ID-xxx.OrganizationEdit.xxxxx-unknown-ID-xxx
Can you please help, Thanks
Hi Laura,
First of all thank you for the wonderfull article you are posting on your blog.
We have created a WebPart that we have published to Teams that would give owners the possibility to modify the external sharing setting (“AllowToAddGuests”) from a tab in their Teams.
We are experiencing a problem when we try to do the set of AllowToAddGuests using an owner account. With global admin works without any issue.
The Teams app has :
{
“resource”: “Microsoft Graph”,
“scope”: “Directory.ReadWrite.All”
}
As per MS Graph docs https://docs.microsoft.com/en-us/graph/api/directorysetting-update?view=graph-rest-beta&tabs=http should work fine with delegated.
If I execute the graph call in the graph explorer using the owner user it gives the same access error.
All permissions are granted at admin level.
If a global admin is used, then all works fine.
The error I am receiving is the following:
{
“error”: {
“code”: “Authorization_RequestDenied”,
“message”: “Insufficient privileges to complete the operation.”,
“innerError”: {
“date”: “2020-07-02T15:18:56”,
“request-id”: “84fe9be9-a4b0-4023-93e6-68dd780ce2ea”
}
}
}
Has the owner the possibility to change the flag AllowToAddGuests or should I do this via an App reg?
Thank you in advance for your answer.
Regards,
Anisia Pop
Hi Anisia,
I’d try including also the “Directory.AccessAsUser.All” permission. If that doesn’t do the trick, then it definitely sounds like you need to be an O365 group admin to change that setting for groups when using delegated permissions. Instead of granting admin privileges, I’d call an Azure function from your SPFx web part, and in the Azure function change that setting for the group using app permissions.
Laura
Hi Laura,
Thanks for the article! Do you know if you can disable external sharing on a private channel, which has its own site collection, but not a separate group (from what I can tell).
I’m using Graph to provision Teams and there are private channels as part of the provisioning that I’d like to limit external sharing. It doesn’t seem Graph has an endpoint for this. Will the CSOM example in your post also work for the private channel site? I’d love to use Graph if it’s possible, but I’m open to using the CSOM.
Thanks,
Doug
Laura – your code worked for private channel sites as well. Thanks!
Hi Laura,
What is the reason for adding an Azure AD property “AllowToAddGuests”? I’m not sure I understand the reasoning for that part.
From what I’ve done, disabling the external sharing on the SharePoint site appears to give me all I need, or am I not testing the Groups invitation of an external party properly, to understand this Azure AD property fully.
Thanks,
Jason.
Hi Jason,
The external sharing setting on the modern SharePoint Online team site is different than the AllowToAddGuests setting of the underlying Office 365 group. If you only disable external sharing on the SharePoint site, people can still invite guests to be members of the Office 365 group which means they can get access to Teams conversations, Planner plans, etc.. You can test adding a guest user to the group via Outlook.
Laura