SharePoint Online: Unique Permissions Report using PowerShell

Requirement: Get unique permissions report in SharePoint Online using PowerShell

Unique Permissions Report in SharePoint Online using PowerShell

PowerShell for SharePoint Online Unique Permissions Report

To find unique permissions in SharePoint Online using this PowerShell, set the $SiteURL and $ReportFile parameters and run this script. It generates a CSV file with all sites, lists, and list items with unique permissions from a given site collection. Here is the SharePoint Online PowerShell to get unique permissions:

#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"
#To call a non-generic Load Method
Function Invoke-LoadMethod() {
            [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)

#Function to Get Unique Permission from a Web and its contents - recursively
Function Get-SPOUniquePermissionReport([Microsoft.SharePoint.Client.Web]$Web)
    Write-host -f Yellow "`nSearching Unique Permissions on the Site:"$web.Url

    #Check if the given site is using unique permissions
    Invoke-LoadMethod -Object $Web -PropertyName "HasUniqueRoleAssignments"
    #Get the Root Web
    $RootWeb = $
    ### Check if the web has broken inheritance
    If($Web.HasUniqueRoleAssignments -and $Web.ID -ne $RootWeb.ID)
        #Get Object Details and Send the Data to Report file
        $ObjectName = $Web.Title ;$ObjectType = "Sub Site" ; $ObjectURL = $Web.URL
        "$($ObjectName) `t $($ObjectURL) `t $($ObjectType)" | Out-File $CSVFile -Append
        Write-host -f Green "`t Unique Permissions Found on Site:" $Web.URL
    ### Get unique permission in Lists
    Write-host -f Yellow "`t Searching Unique Permissions on the Lists..."
    $Lists =  $Web.Lists
    #Exclude system lists
    $ExcludedLists = @("App Packages","appdata","appfiles","Apps in Testing","Cache Profiles","Composed Looks","Content and Structure Reports","Content type publishing error log","Converted Forms",
     "Device Channels","Form Templates","fpdatasources","Get started with Apps for Office and SharePoint","List Template Gallery", "Long Running Operation Status","Maintenance Log Library", "Style Library",
     ,"Master Docs","Master Page Gallery","MicroFeed","NintexFormXml","Quick Deploy Items","Relationships List","Reusable Content","Search Config List", "Solution Gallery", "Site Collection Images",
     "Suggested Content Browser Locations","TaxonomyHiddenList","User Information List","Web Part Gallery","wfpub","wfsvc","Workflow History","Workflow Tasks", "Preservation Hold Library")
    #Iterate through each list
    ForEach($List in $Lists)
        If($ExcludedLists -NotContains $List.Title -and $List.Hidden -eq $false)
            #Check if the given site is using unique permissions
            Invoke-LoadMethod -Object $List -PropertyName "HasUniqueRoleAssignments"
            #Check if List has unique permissions
                #Send Data to CSV File
                $ObjectTitle = $List.Title
                $ObjectURL = $("{0}{1}" -f $Web.Url.Replace($Web.ServerRelativeUrl,''), $List.RootFolder.ServerRelativeUrl)                
                $ObjectType = "List/Library"
                "$($ObjectTitle) `t $($ObjectURL) `t $($ObjectType)" | Out-File $CSVFile -Append

                Write-host -f Green "`t`tUnique Permissions Found on the List: '$($List.Title)'"
            Write-host -f Yellow "`t`t Searching Unique Permissions on the Lists Items of '$($List.Title)'"

            #Query to get list items in batches
            $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
            $Query.ViewXml = "<View Scope='RecursiveAll'><RowLimit>2000</RowLimit></View>"

            ### Get unique permission on List items
            Do {  
                #Get all items from the list
                $ListItems = $List.GetItems($Query)
                $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
                #Loop through each List item
                ForEach($ListItem in $ListItems)
                    Invoke-LoadMethod -Object $ListItem -PropertyName "HasUniqueRoleAssignments"
                    If ($ListItem.HasUniqueRoleAssignments -eq $true)
                        #Send Data to CSV File
                        $ObjectType = "List Item/Folder"
                        #Get the URL of the List Item
                        Invoke-LoadMethod -Object $ListItem.ParentList -PropertyName "DefaultDisplayFormUrl"
                        $DefaultDisplayFormUrl = $ListItem.ParentList.DefaultDisplayFormUrl
                        $ObjectURL = $("{0}{1}?ID={2}" -f $Web.Url.Replace($Web.ServerRelativeUrl,''), $DefaultDisplayFormUrl,$ListItem.ID)
                        $ObjectTitle = $ListItem["Title"]
                        "$($ObjectTitle) `t $($ObjectURL) `t $($ObjectType)" | Out-File $CSVFile -Append

                        Write-host  -ForegroundColor Green "`t`t`t Unique Permissions Found on Item ID:" $ListItem.ID
            } While ($Query.ListItemCollectionPosition -ne $null)
    #Process each subsite in the site
    $Subsites = $Web.Webs
    Foreach ($SubSite in $Subsites)
        #Call the function Recursively
#Config Parameters
$SiteURL= ""
$CSVFile = "C:\Temp\UniquePermissionsRpt.csv"

#Get Credentials to connect
$Cred = Get-Credential
Try {
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName,$Cred.Password)
    #Get the Web
    $Web = $Ctx.Web

    #Write CSV (TAB Separated) File Header
    "Title `t URL `t Object" | Out-File $CSVFile
    #Call the function to get unique permissions from the site collection
    Get-SPOUniquePermissionReport $Web
Catch {
    write-host -f Red "Error:" $_.Exception.Message

This PowerShell script gets you the list of objects such as site, list, or library, list items with broken permission inheritance in a given site collection. If you want to get a report on who has access to what, use this PowerShell script: SharePoint Online: Site Collection Permission Report using PowerShell.

If you need to find subsites, lists, and libraries or list items with unique permissions, use the below scripts:

Salaudeen Rajack

Salaudeen Rajack - SharePoint Expert with Two decades of SharePoint Experience. Love to Share my knowledge and experience with the SharePoint community, through real-time articles!

2 thoughts on “SharePoint Online: Unique Permissions Report using PowerShell

  • This looks like just the kind of thing I need right now, but unfortunately it does not work with MFA enabled accounts. Would it be possible to change the script to take MFA into account?

  • Really thank you for the scripts. I had checked with the CSV. I found that the CSV shows the items title, URL, Object but with no unique permission described. May we be able to get more information about the unique items? Like what is that unique permission and the parties. Thank you.


Leave a Reply

Your email address will not be published.