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

In SharePoint Online, it’s important to keep track of the permissions assigned to each site, list, and library. However, this can be a difficult task, especially in large and complex environments. A unique permissions report provides a clear and concise overview of the permissions assigned to each item in a SharePoint Online site, making it easier to manage permissions and ensure compliance with security policies.

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"
  
#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
    $Web.Retrieve("HasUniqueRoleAssignments")
    $Ctx.ExecuteQuery()
     
    #Get the Root Web
    $RootWeb = $ctx.site.RootWeb
    $Ctx.Load($RootWeb)
    $Ctx.ExecuteQuery()
 
    ### 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
    $Ctx.Load($Lists)
    $Ctx.ExecuteQuery()
 
    #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)
    {
        $Ctx.Load($List)
        $Ctx.ExecuteQuery()
 
        If($ExcludedLists -NotContains $List.Title -and $List.Hidden -eq $false)
        {
            #Check if the given site is using unique permissions
            $List.Retrieve("HasUniqueRoleAssignments")
            $Ctx.ExecuteQuery()
  
            #Check if List has unique permissions
            If($List.HasUniqueRoleAssignments)
            {
                #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)
                $Ctx.Load($ListItems)
                $Ctx.ExecuteQuery()
            
                $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
   
                #Loop through each List item
                ForEach($ListItem in $ListItems)
                {
                    $ListItem.Retrieve("HasUniqueRoleAssignments")
                    $Ctx.ExecuteQuery()
                    If ($ListItem.HasUniqueRoleAssignments -eq $true)
                    {
                        #Send Data to CSV File
                        $ObjectType = "List Item/Folder"
                        #Get the URL of the List Item
                        $ListItem.ParentList.Retrieve("DefaultDisplayFormUrl")
                        $Ctx.ExecuteQuery()
                        $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
    $Ctx.Load($Subsites)
    $Ctx.ExecuteQuery()        
    Foreach ($SubSite in $Subsites)
    {
        #Call the function Recursively
        Get-SPOUniquePermissionReport($Subsite)
    }
}
 
#Config Parameters
$SiteURL= "https://crescent.sharepoint.com/sites/marketing"
$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
    $Ctx.Load($Web)
    $Ctx.ExecuteQuery()

    #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.

In summary, Generating a unique permissions report in SharePoint Online using PowerShell is a straightforward process that can be accomplished by using the PowerShell script explained above. By using PowerShell cmdlets to retrieve the permissions for each item in your site, you can quickly create a report that provides a comprehensive overview of your SharePoint Online sites.

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?

    Reply
  • 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.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *