SharePoint Online: Delete Unique Permissions for All Items in a List using PowerShell

Requirement: Reset all customized permissions in all documents of a SharePoint online document library.

By default, Permissions are inherited from their parent in all levels of SharePoint. E.g. Site inherits permissions from its parent site collection (or parent site), lists and libraries inherits permissions from the site, items in the list inherits permissions from the list. So, If you make any change in permissions at the parent level, any child underneath, automatically inherits the permission changes you made in the parent, unless the child is using its own unique permissions.

At times, you may have to set up unique permissions at granular level and of course, you may have to reset the broken permissions.

How to Delete Unique Permissions in SharePoint?
To reset custom permissions on SharePoint list items or documents,
  • Navigate to the SharePoint library where your documents are stored
  • Select the document >> Click on "Shared With" under Manage group in the ribbon 
  • Click on Advanced >> and click on "Delete Unique Permissions" button from the ribbon. Confirm the prompt once!
delete unique permissions in sharepoint online using powershell

Alright, now the permissions are set to Inherited from the parent library of the document. But wait, Picking each and every individual document and repeating these steps to remove unique permissions is tedious, wouldn't you agree? So, I wrote this PowerShell script to Reset Broken Inheritance on all items in a SharePoint List.

PowerShell to Remove Unique Permissions from a SharePoint Online List Item:
Here is how to remove all unique permissions in SharePoint Online list item
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

#Function to remove unique permissions and inherit from the parent
Function Remove-ListItemUniquePermissions
{
param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $ListName,
        [Parameter(Mandatory=$true)] [string] $ItemID        
    )

    Try {
        $Cred= Get-Credential
        $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)

        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Credentials

        #Remove unique permissions and reset inheritance
        $List=$Ctx.Web.Lists.GetByTitle($ListName)
        $ListItem=$List.GetItemByID($ItemID)
        $ListItem.ResetRoleInheritance()
        $Ctx.ExecuteQuery()

        Write-Host "Unique Permissions are removed and inherited from the Parent!" -ForegroundColor Green
    }

    Catch {
        write-host -f Red "Error Deleting Unique Permissions!" $_.Exception.Message
    } 
}

#Parameters
$SiteURL="https://crescent.sharepoint.com"
$ListName="Projects"
$ItemID="25"

#Call the function to remove unique permissions from a list
Remove-ListItemUniquePermissions -SiteURL $SiteURL -ListName $ListName -ItemID $ItemID 

PowerShell Script to Delete Unique Permissions for All List Items in SharePoint Online:
#Load SharePoint Online Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
  
##Variables for Processing
$SiteUrl = "https://crescent.sharepoint.com/sites/Sales/"
$ListName= "Documents"
$UserName= "Salaudeen@crescent.com"
$Password ="Password goes here"
 
#Setup Credentials to connect
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,(ConvertTo-SecureString $Password -AsPlainText -Force))
 
#Set up the context
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl) 
$Context.Credentials = $credentials
  
#Get the List
$List = $Context.web.Lists.GetByTitle($ListName)
 
#Get All List Items
$Query = New-Object Microsoft.SharePoint.Client.CamlQuery
$ListItems = $List.GetItems($Query)
$Context.Load($ListItems)
$Context.ExecuteQuery()

Write-host "Total Items Found:"$ListItems.Count
#Iterate through each list item
 $ListItems |  foreach {
    #Delete Unique Permission
    $_.ResetRoleInheritance()
 }
$Context.ExecuteQuery()

Write-host "Broken Permissions are Deleted on All Items!" -ForegroundColor Green
There are two improvements can be made in the above script:
  1. The above script doesn't handle large lists with > 5000 items. 
  2. The above script simply resets inheritance without checking if the list item has unique permissions.
So, lets fix the above issues and here is the updated script:

Delete Unique Permissions in SharePoint Online using PowerShell
Here is the PowerShell to reset unique permissions in large lists or document libraries (with more than 5000 items!)
#Load SharePoint Online Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

#To call a non-generic method Load
Function Invoke-LoadMethod() {
    param(
            [Microsoft.SharePoint.Client.ClientObject]$Object = $(throw "Please provide a Client Object"),
            [string]$PropertyName
        ) 
   $ctx = $Object.Context
   $load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load") 
   $type = $Object.GetType()
   $clientLoad = $load.MakeGenericMethod($type)
  
   $Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name)
   $Expression = [System.Linq.Expressions.Expression]::Lambda([System.Linq.Expressions.Expression]::Convert([System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$PropertyName),[System.Object] ), $($Parameter))
   $ExpressionArray = [System.Array]::CreateInstance($Expression.GetType(), 1)
   $ExpressionArray.SetValue($Expression, 0)
   $clientLoad.Invoke($ctx,@($Object,$ExpressionArray))
}
   
##Variables for Processing
$SiteUrl = "https://crescent.sharepoint.com"
$ListName= "Documents"
  
#Get Credentials to connect
$Cred= Get-Credential
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
  
#Set up the context
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl) 
$Context.Credentials = $Credentials
   
#Get the List
$List = $Context.web.Lists.GetByTitle($ListName)

$Query = New-Object Microsoft.SharePoint.Client.CamlQuery
$Query.ViewXml = "<View Scope='RecursiveAll'><RowLimit>2000</RowLimit></View>"

#Batch process list items - to mitigate list threashold issue on larger lists
Do {  
    #Get items from the list in batches
    $ListItems = $List.GetItems($Query)
    $Context.Load($ListItems)
    $Context.ExecuteQuery()
          
    $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
 
    #Loop through each List item
    ForEach($ListItem in $ListItems)
    {
        Invoke-LoadMethod -Object $ListItem -PropertyName "HasUniqueRoleAssignments"
        $Context.ExecuteQuery()
        if ($ListItem.HasUniqueRoleAssignments -eq $true)
        {
            #Reset Permission Inheritance
            $ListItem.ResetRoleInheritance()
            Write-host  -ForegroundColor Yellow "Inheritence Restored on Item:" $ListItem.ID
        }
    }
    $Context.ExecuteQuery()
} While ($Query.ListItemCollectionPosition -ne $null)
 
Write-host "Broken Permissions are Deleted on All Items!" -ForegroundColor Green

Last but not least: You need SharePoint online Client SDK installed on your client machine to use this code: https://www.microsoft.com/en-us/download/details.aspx?id=42038
SharePoint Online: Delete Unique Permissions for All Items in a List using PowerShell SharePoint Online: Delete Unique Permissions for All Items in a List using PowerShell Reviewed by Salaudeen Rajack on February 20, 2016 Rating: 5

14 comments:

  1. This was very usable. I noticed when running the code on a library with more than 1000 items that I got an error message complaining about not enough resources in SPO to complete the request. I changed the foreach to the following:
    # Start with 100 items
    $Counter = 100

    #Iterate through each list item
    $ListItems | foreach {
    if ($Counter > 0) {
    #Delete Unique Permission
    $_.ResetRoleInheritance()
    $Counter = $Counter - 1
    }
    else {
    $_.ResetRoleInheritance()
    $Context.ExecuteQuery()
    $Counter = 100
    }
    }
    $Context.ExecuteQuery()

    This way the changes are made on every 100 items and then for the last items at the end. I've used it on three different libraries without errors.

    ReplyDelete
  2. Great code, it worked a treat! I did strike an issue where SP Online has an unchangeable list view limit of 5000. To get around this I replace the CAML row limit with a query on the Item Id as per below

    5000

    to

    600010000

    ReplyDelete
    Replies
    1. Could you expand on this a little more?
      Thanks!

      Delete
  3. Would this work for the sharepoint sites behind Microsoft teams?

    ReplyDelete
    Replies
    1. Yes! Script just needs the Site URL and List name.

      Delete
  4. Found an issue with the script. Line 41 needs to come out of the DO loop. Otherwise it will just keep iterating over the same items over and over, and won't go inside any folders properly. If you bring 41 out of the DO loop it then iterates recursively like it is supposed to. Great script!

    ReplyDelete
    Replies
    1. Seriously? The "Do" loop executes for the first time, gets 2000 list items and the "while" part takes care of next execution or exit from the loop.

      Delete
  5. Is there a way to change the Listname into a subfolder name? So I can process just a part of my list.

    ReplyDelete
  6. Thank you for the scripts.
    I kept getting the message: The sign-in name or password does not match one in the Microsoft account system
    Turns out I had to use an account that did not have MFA enabled.

    ReplyDelete
    Replies
    1. is there a way to adjust the get-credential to support MFA?

      Delete
    2. If MFA is enabled, You can't hard-code credentials!

      Delete
  7. Hi, thank you very much for the script, works well.
    Can this script be modified so that it goes through all document libraries and deletes all unique permissions (i have less than 5000 items within the site bit have 43 libraries which have inherited permissions during migration from file servers)? Thank you in advance

    ReplyDelete

Please Login and comment to get your questions answered!

Powered by Blogger.