By default, lists and their content inherit the groups and permission levels of the site above them in the hierarchy—that is, a list inherits permissions from the site where it is located, and the site, in turn, inherits permissions from its parent site. If you make a change in the parent site, its sub-sites, their lists, and their contents automatically get the same change.1 

This inheritance is often broken because not all site users should have access to all lists and all documents on the site. It is often dictated by security reasons, e.g. the list contains sensitive data, and you might want to restrict who can see it.  As the site grows, the number of lists and libraries increases until you end up with hundreds of lists with unique permissions, which you no longer need.

Time for a fresh start? 

Broken permissions is not a setting for life - you don't have to stick to them. In any moment you can and should change them if you don't like them or they no longer apply to your situation. Using one button, you can restore permissions from the parent element (site) and from now on whatever changes will be applied to the site, will replicate also to the list.



 
Watch out -  If you choose to resume permissions inheritance, you lose any unique permission settings on the content.2


Aye, there's the rub  
Do you have a hundred lists? Well, there is a hundred clicks ahead for you. Currently, there is no option using the Graphic User Interface to delete unique permissions for more than one element. So whether it's a list, a site, or an item, you have to go one by one. SharePoint Online Management Shell with its 30+ cmdlets also doesn't provide an answer (not yet, maybe in the future :) )

This is where scripting comes in handy. 

CSOM stands for client-side object model which allows you to authenticate to SharePoint Online and perform operations on its elements. Let's open Powershell ISE and look at it from Powershell perspective:

1. Install SharePoint Online SDK


2. After you have installed the SDK, you need to refer it in your script:

# Paths to SDK. Please verify location on your computer.
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "c:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

3. Create a context for your operations. The URL refers to a site where the lists are located. It can be a site collection or one of the subsites.

$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($Url)

4. Add the credentials of the admin. You cannot perform operations against a site to which you don't have permissions!
The password has to be a secure string.

$password = ConvertTo-SecureString -string $AdminPassword -AsPlainText -Force
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $password)

5. Now you need to load the elements on which you want to perform operations because before you can access the value properties of a client object, you must call the LOAD method3

$ctx.Load($ctx.Web.Lists)
$ctx.Load($ctx.Web)
$ctx.ExecuteQuery()

6.  ExecuteQuery()  performs the operations that you stated in the lines above. This virtual method is “synchronous”, which means that code execution is blocked until a response is received from the server. If the caller does not want to be blocked and the caller is managed, the caller should evoke the ExecuteQueryAsync() method.4

7. Now let's create a simple foreach loop:

foreach( $ll in $ctx.Web.Lists)
  {
             
        $ll.BreakRoleInheritance($true, $false)
        $ll.Update()


8. Notice that I didn't close the loop yet. It is because - in order to run this operation - we need an .ExecuteQuery().

$ctx.ExecuteQuery()

9. What if we get an error? What if the list doesn't support modifying permissions, e.g. "appdata" or "Composed Looks"? We need to provide some error handling. Try and catch will do the job:

try
        {
        $ctx.ExecuteQuery()
 
        }
catch
        {
 
        }

10. Because it would be cool to inform the user (or yourself) whether the operation was successful, we can add simple Write-Host cmdlet, which will display a message in Powershell:

Write-Host "Deleted unique permissions for " $ll.Title


11. And the full loop:

foreach( $ll in $ctx.Web.Lists)
  {
             
    $ll.ResetRoleInheritance()
    $ll.Update()
 
        try
        {
        $ctx.ExecuteQuery()
        Write-Host "Deleted unique permissions for " $ll.Title
        }
        catch
        {
        Write-Host "Failed to restore permissions for " $ll.Title
        }
}

You can enjoy the full script here

Related scripts:

Break inheritance for all lists

Modify inherited permissions for a SharePoint Online site (module)

Modify list permissions with Powershell cmdlets (module)

Delete unique permissions (C# program)

Get lists with unique permissions (C# program)


Other languages


This site is available in other languages:
Wiki: Usuń unikatowe uprawnienia dla wielu list używając CSOM (PL-pl)

shopify analytics