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!
Hello,
Great article, but it seems the title article ‘COMPLETELY DISABLE EXTERNAL SHARING’ is not accurate.
In fact we do still have right to share files and folders within SharePoint even if the guest access is blocked. We have to go to SharePoint admin center, go to site related to the O365 group and block share with external and.. done 🙂
Forget about my comment, I did not go trough the next part of your article…. 🙂
Hi Laura, thanks for the post. Have you tried to call the graph API post from PowerShell so that the external sharing get disabled for the group? I’m struggling to adapt your C# code to PowerShell and call the graph API query
Some here. Without an endpoint for MS Graph and C# it’s impossible to set this stuff except if you are azure ad admin. 🙁
Sorry this was nonesense. I did’nt see your C# Graph examples for this. Thank you!
@Quantum: Great that you got the C# sample working. 🙂
@Luis: I know this reply comes quite late but earlier this month the Microsoft Graph team released a new Microsoft Graph PowerShell module. I recommend you give that a go as it doesn’t require you to do authentication and build the REST requests yourself.
Laura
Is there a way to allow external guest IM to all Teams/channels but prevent one-to-one chats?
Hi Walter,
Yes, there is — though it is a tenant-wide setting. You can do this through the UI by going to the Teams admin center -> Org-wide settings -> Guest access -> Enable “Allow guest access in Teams” and then disabled “Chat” under messaging.
Laura
I’m having exactly the same issue when doing this with PowerShell. It seems to require Global Admin rights to execute the New-AzureADObjectSetting cmdlet. I’ve tried every possible individual admin role, no luck so far.
I’m wondering if it’s because we need to use the AzureAD Preview module, if there’s a limitation there perhaps?
Hi Richard,
Thank you for sharing your findings! It’s good to know that you need to be a global admin to make those changes.
The global admin permission is probably required simply because you are creating a new object setting in Azure AD. I think I’ve always run that commandlet as a global administrator in the past anyway, so I can’t personally say for sure that it didn’t require those permissions in the past. If it didn’t, I’ll take your word for it. 🙂 However, I can’t say why it changed if it did.
Laura
Hi
Seems like Microsoft has changed the permissions required for the PowerShell option recently! All the sudden it fails with a Forbidden error – seems like Global Admin is required now!? Anything you have seen?
Hi Henrik,
I can’t say that I’ve faced this issue. Are you sure you are authenticating successfully?
Laura