Last Updated on June 22, 2024
Need a permissions report?
In this guide, I will walk you through the steps of generating a SharePoint site permissions report using PowerShell.
Let’s get started.
Table of Contents:
What is a permissions report?
A permissions report in SharePoint provides a detailed view of who has access to what within a site.
It helps site collection administrators manage and audit permissions efficiently:
- Identifies all users and groups with access to the site
- Shows the level of access each user or group has
- Highlights permissions at different levels, such as site, list, and item levels
SharePoint Online permissions reports are essential for maintaining security and compliance.
They ensure that only authorized users have access to sensitive information.
Administrators can quickly identify and address any discrepancies or unwanted access.
This helps in preventing data breaches and ensuring that the SharePoint environment is secure and well-managed.
👉 Related: How to Check User Permissions in SharePoint Online (Guide)
Sign up for exclusive updates, tips, and strategies
Generating Site Permissions Report
Using PowerShell scripts, you can efficiently extract detailed permissions data and export it into a CSV file for analysis.
Here are the steps:
- Define the site URL and the path where you want to save the report.
- Use the PnP PowerShell module to connect to your SharePoint Online site.
- Loop through each role assignment to collect permission details.
- Save the collected data into a CSV file for further analysis.
Here’s an example of a PowerShell script for this process:
# Parameters
$SiteURL = "https://yourtenant.sharepoint.com/sites/yoursite"
$ReportOutput = "C:\Temp\SitePermissionRpt.csv"
# Connect to Site
Connect-PnPOnline -Url $SiteURL -Interactive
# Get the web
$Web = Get-PnPWeb -Includes RoleAssignments
# Initialize an array to hold permission data
$PermissionData = @()
# Loop through each permission assigned
ForEach ($RoleAssignment in $Web.RoleAssignments) {
# Get the Permission Levels assigned and Member
Get-PnPProperty -ClientObject $RoleAssignment -Property RoleDefinitionBindings, Member
# Collect Permission Data
$Permissions = New-Object PSObject
$Permissions | Add-Member NoteProperty Name($RoleAssignment.Member.Title)
$Permissions | Add-Member NoteProperty Type($RoleAssignment.Member.PrincipalType)
$Permissions | Add-Member NoteProperty PermissionLevels(($RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name) -join ",")
$PermissionData += $Permissions
}
# Export to CSV
$PermissionData | Export-Csv -Path $ReportOutput -NoTypeInformation
Write-Host "Site Permission Report Generated Successfully!"
Let me explain what happened:
- The
$SiteURL
variable holds the URL of your SharePoint Online site, and $ReportOutput specifies the file path where the CSV report will be saved. Connect-PnPOnline
is used to authenticate and connect to the specified SharePoint Online site.Get-PnPWeb -Includes RoleAssignments
retrieves the web object along with its role assignments.- A loop goes through each role assignment, retrieves its properties, and stores the data in the
$PermissionData
array. - The collected permission data is exported to a CSV file using Export-Csv.
This is the CSV that was generated:

Nice! 👏
Advanced Reporting Options
You can also implement advanced options to provide deeper insights and get more detailed data.
Some advanced techniques include:
Recursive permissions reporting
For a thorough audit, you may want to include permissions for all subsites and nested objects within your SharePoint Online site.
This involves recursively scanning each subsite and its contents:
# Function to Get Web Permissions Recursively
Function Get-PnPWebPermissions([Microsoft.SharePoint.Client.Web]$Web) {
# Get Web Permissions
Get-Permissions -Object $Web
# Get Permissions for Lists and Libraries
Get-PnPListPermissions -Web $Web
# Recursively process each subsite
$Web.Webs | ForEach-Object {
Get-PnPWebPermissions -Web $_
}
}
# Start the recursive permission retrieval
$RootWeb = Get-PnPWeb
Get-PnPWebPermissions -Web $RootWeb
Item-level permissions
To capture permissions at the item level, modify the script to loop through all items within a list and check for unique permissions.
Example script:
# Function to Get List Item Permissions
Function Get-PnPListItemPermissions([Microsoft.SharePoint.Client.List]$List) {
$ListItems = Get-PnPListItem -List $List -PageSize 500
ForEach ($Item in $ListItems) {
$HasUniquePermissions = Get-PnPProperty -ClientObject $Item -Property HasUniqueRoleAssignments
If ($HasUniquePermissions) {
Get-Permissions -Object $Item
}
}
}
# Call the function for each list
$Lists = Get-PnPList
ForEach ($List in $Lists) {
Get-PnPListItemPermissions -List $List
}
Including group members
Often, you need to see not only the group names but also the members within each group.
Extend the script to expand groups and include individual user permissions:
# Function to Expand Groups and Get Members
Function Get-GroupMembers([Microsoft.SharePoint.Client.Group]$Group) {
$GroupUsers = Get-PnPProperty -ClientObject $Group -Property Users
ForEach ($User in $GroupUsers) {
$Permissions = New-Object PSObject
$Permissions | Add-Member NoteProperty Name($User.Title)
$Permissions | Add-Member NoteProperty Type("User")
$Permissions | Add-Member NoteProperty PermissionLevels(($Group | Select -ExpandProperty RoleDefinitionBindings) -join ",")
$PermissionData += $Permissions
}
}
# Integrate with main script
ForEach ($RoleAssignment in $Web.RoleAssignments) {
If ($RoleAssignment.Member.PrincipalType -eq "SharePointGroup") {
Get-GroupMembers -Group $RoleAssignment.Member
}
}
Filtering and customizing reports
You might want to filter permissions by specific criteria such as user roles, permissions levels, or specific Sharepoint sites.
Adjust the script to include these filters:
# Filter by Specific Role
ForEach ($RoleAssignment in $Web.RoleAssignments) {
$RoleBindings = $RoleAssignment.RoleDefinitionBindings | Where-Object { $_.Name -ne "Limited Access" }
If ($RoleBindings) {
# Collect data for filtered roles
$Permissions = New-Object PSObject
$Permissions | Add-Member NoteProperty Name($RoleAssignment.Member.Title)
$Permissions | Add-Member NoteProperty Type($RoleAssignment.Member.PrincipalType)
$Permissions | Add-Member NoteProperty PermissionLevels(($RoleBindings | Select -ExpandProperty Name) -join ",")
$PermissionData += $Permissions
}
}
Common Issues and Troubleshooting
Unfortunately, you may encounter several issues. 😰
Well, that’s not unlikely when using PowerShell, but these issues may produce incomplete reports.
Here are common issues you may encounter and what you can do:
Issue 1: List not found error
This error occurs when the script cannot find a specified list.
Ensure that the list name is correct and exists on the site.
Use the Get-PnPList
cmdlet to verify the list’s presence:
$Lists = Get-PnPList
ForEach ($List in $Lists) {
Write-Host $List.Title
}
Issue 2: Collection not initialized
This error means the script is trying to access a collection that has not been loaded or initialized.
Explicitly request the collection using the Get-PnPProperty
cmdlet before accessing it.
Like this:
$Webs = Get-PnPProperty -ClientObject $Web -Property Webs
Issue 3: RoleDefinitionBindings property not found
This error occurs when the script cannot find the RoleDefinitionBindings
property in a group.
For this, ensure the RoleAssignments
property is correctly loaded and accessed.
You can do it like this:
$RoleAssignments = Get-PnPProperty -ClientObject $Object -Property RoleAssignments
ForEach ($RoleAssignment in $RoleAssignments) {
$RoleAssignment.RoleDefinitionBindings | ForEach-Object {
# Process permissions
}
}
Issue 4: Method invocation failure
This error happens when using methods or properties that don’t exist for an object.
You can check that the objects’ properties are correctly retrieved and used.
$Permissions = @()
$RoleAssignments = Get-PnPProperty -ClientObject $Object -Property RoleAssignments
ForEach ($RoleAssignment in $RoleAssignments) {
$Permissions += New-Object PSObject -Property @{
Name = $RoleAssignment.Member.Title
Type = $RoleAssignment.Member.PrincipalType
PermissionLevels = ($RoleAssignment.RoleDefinitionBindings | Select-Object -ExpandProperty Name) -join ","
}
}
Additional information:
- Always test scripts in a non-production SharePoint Online environment first to avoid disrupting live sites.
- Use verbose logging (
Write-Host
) to track the script’s progress and identify where issues occur. - Regularly update your PowerShell modules (
Update-Module -Name PowerShellGet
) to ensure compatibility with SharePoint Online updates.
Anyway, got any questions on generating a site collection permissions report? Let me know.
For any business-related queries or concerns, contact me through the contact form. I always reply. 🙂
Is there a way to get retrieve all the permissions for a specific user for an entire site collection down to the item level?
Hi Mr. SharePoint, PowerShell like in this article can work well, however, I just want to share a new tool to build these SharePoint Permission reports, that we (Cognillo) are now offering for free with the new SharePoint Essentials Toolkit 2025 release. Yes, it is completely free. Here is an article that explains how to get it and what it includes. https://www.cognillo.com/blog/free-sharepoint-permission-reports Mr. SharePoint, maybe you have a need for this as well, it has no cost and it also can do SharePoint Site Analytics, copying of lists and libraries for free in this Community Edition. We are providing this… Read more »