Get SharePoint Folder Permissions Using PnP PowerShell

Managing permissions in a SharePoint Online document library can become difficult when the library contains multiple folders, subfolders, files, and unique permission assignments. A permissions report helps administrators identify who has access to each folder or file, which permission level they have, and whether the permission is inherited or assigned directly.

In this tutorial, you will learn how to use PnP PowerShell to get SharePoint folder permissions, file permissions, and list item permissions. The script exports the results to a CSV file that you can open in Microsoft Excel for review, auditing, or compliance reporting.

The report includes:

  • Folder, file, list item, or library name
  • Direct URL to the SharePoint object
  • Whether the object has unique permissions
  • User or SharePoint group name
  • Email address
  • Principal type
  • Assigned permission levels
  • Whether access was granted directly or through a SharePoint group

Prerequisites

Before running the script, make sure you have completed the following requirements:

  • Install the latest PnP PowerShell module.
  • Register a Microsoft Entra ID application and copy its client ID.
  • Ensure that the signed-in account has sufficient access to read permissions from the target SharePoint site, library, folders, and files.
  • Create a local folder to the CSV permissions report. Note: The output file is a CSV file. You can open it directly in Microsoft Excel after the script finishes.

PnP PowerShell Script to Get SharePoint Folder Permissions

The following PnP PowerShell script retrieves permissions from a SharePoint document library. It can scan the library itself and, when enabled, every folder, subfolder, file, and list item in that library.

Keep the script unchanged and update the configuration values at the beginning.

$SiteURL="https://.sharepoint.com/sites/RetailManagementSite"
$ListName = "Employee Satisfaction Survey PDF Files"
$ReportFile="D:\Temp Folder\Employee Satisfaction Survey PDF Files.csv"

If (Test-Path $ReportFile) {
Remove-Item $ReportFile
}

Function Get-LibraryPermissions([Microsoft.SharePoint.Client.SecurableObject] $Object) {
Switch($Object.TypedObject.ToString()) {
"Microsoft.SharePoint.Client.ListItem" {
If($Object.FileSystemObjectType -eq "Folder") {
$ObjectType = "Folder"

#Get the URL of the Folder
$Folder = Get-PnPProperty -ClientObject $Object -Property Folder
$ObjectTitle = $Object.Folder.Name
$ObjectURL = ("{0}{1}" -f $Web.Url.Replace($Web.ServerRelativeUrl,''),$Object.Folder.ServerRelativeUrl)
}
Else {
Get-PnPProperty -ClientObject $Object -Property File, ParentList

If($Object.File.Name -ne $Null) {
$ObjectType = "File"
$ObjectTitle = $Object.File.Name
$ObjectURL = ("{0}{1}" -f $Web.Url.Replace($Web.ServerRelativeUrl,''),$Object.File.ServerRelativeUrl)
}
else {
$ObjectType = "List Item"
$ObjectTitle = $Object["Title"]

#Get the URL of the List Item
$DefaultDisplayFormUrl = Get-PnPProperty -ClientObject $Object.ParentList -Property DefaultDisplayFormUrl
$ObjectURL = ("{0}{1}?ID={2}" -f $Web.Url.Replace($Web.ServerRelativeUrl,''), $DefaultDisplayFormUrl,$Object.ID)
}
}
}

Default {
$ObjectType = "List or Library"
$ObjectTitle = $Object.Title

#Get the URL of the List or Library
$RootFolder = Get-PnPProperty -ClientObject $Object -Property RootFolder
$ObjectURL = ("{0}{1}" -f $Web.Url.Replace($Web.ServerRelativeUrl,''), $RootFolder.ServerRelativeUrl)
}
}

Get-PnPProperty -ClientObject $Object -Property HasUniqueRoleAssignments, RoleAssignments

$HasUniquePermissions = $Object.HasUniqueRoleAssignments
$PermissionCollection = @()

Foreach($RoleAssignment in $Object.RoleAssignments) {
Get-PnPProperty -ClientObject $RoleAssignment -Property RoleDefinitionBindings, Member

$PermissionType = $RoleAssignment.Member.PrincipalType
$PermissionLevels = $RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name
$PermissionLevels = ($PermissionLevels | Where { $_ -ne "Limited Access"}) -join ","

If($PermissionLevels.Length -eq 0) {
Continue
}

If($PermissionType -eq "SharePointGroup") {
$GroupMembers = Get-PnPGroupMember -Identity $RoleAssignment.Member.LoginName

If($GroupMembers.count -eq 0) {
Continue
}

$GroupUsers = ($GroupMembers | Select -ExpandProperty Title) -join "; "

$Permissions = New-Object PSObject
$Permissions | Add-Member NoteProperty Object($ObjectType)
$Permissions | Add-Member NoteProperty Title($ObjectTitle)
$Permissions | Add-Member NoteProperty URL($ObjectURL)
$Permissions | Add-Member NoteProperty HasUniquePermissions($HasUniquePermissions)
$Permissions | Add-Member NoteProperty Users($GroupUsers)
$Permissions | Add-Member NoteProperty Email($RoleAssignment.Member.Email)
$Permissions | Add-Member NoteProperty Type($PermissionType)
$Permissions | Add-Member NoteProperty Permissions($PermissionLevels)
$Permissions | Add-Member NoteProperty GrantedThrough("SharePoint Group: $($RoleAssignment.Member.LoginName)")

$PermissionCollection += $Permissions
}
Else {
$Permissions = New-Object PSObject
$Permissions | Add-Member NoteProperty Object($ObjectType)
$Permissions | Add-Member NoteProperty Title($ObjectTitle)
$Permissions | Add-Member NoteProperty URL($ObjectURL)
$Permissions | Add-Member NoteProperty HasUniquePermissions($HasUniquePermissions)
$Permissions | Add-Member NoteProperty Users($RoleAssignment.Member.Title)
$Permissions | Add-Member NoteProperty Email($RoleAssignment.Member.Email)
$Permissions | Add-Member NoteProperty Type($PermissionType)
$Permissions | Add-Member NoteProperty Permissions($PermissionLevels)
$Permissions | Add-Member NoteProperty GrantedThrough("Direct Permissions")

$PermissionCollection += $Permissions
}
}

$PermissionCollection | Export-CSV $ReportFile -NoTypeInformation -Append
}

Function Generate-LibraryPermissionsReport() {
[cmdletbinding()]

Param (
[Parameter(Mandatory=$false)]
[String] $SiteURL,

[Parameter(Mandatory=$false)]
[String] $ListName,

[Parameter(Mandatory=$false)]
[String] $ReportFile,

[Parameter(Mandatory=$false)]
[switch] $ScanItemLevel,

[Parameter(Mandatory=$false)]
[switch] $IncludeInheritedPermissions
)

Try {
Function Get-PnPListItemsPermission([Microsoft.SharePoint.Client.List]$List) {
Write-host -f Yellow "`t `t Getting Permissions of List Items in the List:"$List.Title

$ListItems = Get-PnPListItem -List $List -PageSize 500
$ItemCounter = 0

ForEach($ListItem in $ListItems) {
If($IncludeInheritedPermissions) {
Get-LibraryPermissions -Object $ListItem
}
Else {
$HasUniquePermissions = Get-PnPProperty -ClientObject $ListItem -Property HasUniqueRoleAssignments

If($HasUniquePermissions -eq $True) {
Get-LibraryPermissions -Object $ListItem
}
}

$ItemCounter++

Write-Progress -PercentComplete ($ItemCounter / ($List.ItemCount) * 100) `
-Activity "Processing Items $ItemCounter of $($List.ItemCount)" `
-Status "Searching Unique Permissions in List Items of '$($List.Title)'"
}
}

$List = Get-PnpList -Identity $ListName -Includes RoleAssignments

Write-host -f Yellow "Getting Permissions of the List '$ListName'..."

Get-LibraryPermissions -Object $List

If($ScanItemLevel) {
Get-PnPListItemsPermission -List $List
}

Write-host -f Green "`t List Permission Report Generated Successfully!"
}
Catch {
write-host -f Red "Error Generating List Permission Report!"
$_.Exception.Message
}
}

Connect-PnPOnline -URL $SiteURL -ClientId "Provide your client ID" -Interactive

$Web = Get-PnPWeb

Generate-LibraryPermissionsReport -SiteURL $SiteURL -ListName $ListName -ReportFile $ReportFile -ScanItemLevel

Update the Script Variables

Before you run the script, update these values with information from your SharePoint environment.

$SiteURL="https://.sharepoint.com/sites/RetailManagementSite"
$ListName = "Employee Satisfaction Survey PDF Files"
$ReportFile="D:\Temp Folder\Employee Satisfaction Survey PDF Files.csv"

For example:

$SiteURL = "https://contoso.sharepoint.com/sites/HR"
$ListName = "Employee Documents"
$ReportFile = "C:\Reports\SharePointFolderPermissions.csv"

If the report file already exists at the selected location, the script removes it before generating a new report.

If (Test-Path $ReportFile) {
Remove-Item $ReportFile
}

Add Your Microsoft Entra ID Client ID

Locate the following line in the script:

Connect-PnPOnline -URL $SiteURL -ClientId "Provide your client ID" -Interactive

Replace "Provide your client ID" with the application or client ID from your Microsoft Entra ID app registration.

Connect-PnPOnline -URL $SiteURL -ClientId "YOUR-CLIENT-ID" -Interactive

The -Interactive parameter opens the Microsoft sign-in window. Sign in with an account that has permission to access the SharePoint site and inspect the library permissions.

Run the SharePoint Permission Report Script

Save the script as a .ps1 file, such as:

Get-SharePoint-Folder-Permissions.ps1

Open PowerShell, navigate to the folder where you saved the script, and run it.

The script connects to your SharePoint Online site, retrieves permissions from the selected library, scans files and folders, and exports the details to the configured CSV file.

When the script completes successfully, you will see the following message:

List Permission Report Generated Successfully!

Open the generated CSV file in Microsoft Excel to review the SharePoint folder permissions and file permissions.

Understanding the Permission Report

The exported CSV report provides a detailed view of permission assignments across the selected SharePoint document library.

Get SharePoint Folder Permissions Using PnP PowerShell
ColumnDescription
ObjectIdentifies whether the entry is a library, folder, file, or list item
TitleShows the name of the SharePoint object
URLProvides a direct link to the folder, file, list item, or library
HasUniquePermissionsShows whether the object has unique permissions instead of inheriting permissions
UsersLists the user name or members of the assigned SharePoint group
EmailShows the email address associated with the assigned user or group
TypeIdentifies the principal type, such as a SharePoint group or user
PermissionsDisplays assigned permission levels, such as Read, Edit, or Full Control
GrantedThroughShows whether access was assigned directly or through a SharePoint group

This report is particularly useful for identifying folders and files with broken permission inheritance. You can also use it to detect unexpected direct permissions, external access, or users who have access through SharePoint groups.

How the Get-LibraryPermissions Function Works

The Get-LibraryPermissions function is responsible for retrieving permission information for a SharePoint object.

It works with the following SharePoint object types:

  • SharePoint list or document library
  • Folder
  • File
  • List item

The function first identifies the object type and retrieves its title and URL. It then checks whether the object has unique role assignments by reading the HasUniqueRoleAssignments property.

Get-PnPProperty -ClientObject $Object -Property HasUniqueRoleAssignments, RoleAssignments

If an object inherits permissions, the HasUniquePermissions value in the report is set to False. If permission inheritance has been broken and the object has its own assignments, the value is set to True.

The function then loops through each role assignment, retrieves the assigned permission levels, and excludes the Limited Access role from the report. This keeps the output focused on meaningful permissions such as Read, Edit, Contribute, Design, or Full Control.

For SharePoint groups, the script retrieves the group members and adds them to the report. For individual users, it records direct permissions and identifies them as Direct Permissions in the GrantedThrough column.

How the Generate-LibraryPermissionsReport Function Works

The Generate-LibraryPermissionsReport function controls the overall permission-reporting process.

It accepts the following parameters:

$SiteURL
$ListName
$ReportFile
$ScanItemLevel
$IncludeInheritedPermissions

The function first retrieves the selected SharePoint list or document library.

$List = Get-PnpList -Identity $ListName -Includes RoleAssignments

It then retrieves the library-level permissions by calling the Get-LibraryPermissions function.

Get-LibraryPermissions -Object $List

When you use the -ScanItemLevel switch, the script also scans every item in the library. This includes folders, subfolders, files, and list items.

Generate-LibraryPermissionsReport -SiteURL $SiteURL -ListName $ListName -ReportFile $ReportFile -ScanItemLevel

For large document libraries, scanning every item can take time because the script must inspect each folder and file individually. The progress bar in PowerShell shows the number of items processed during the scan.

Include Inherited Permissions

By default, the script focuses on items with unique permissions when scanning item-level permissions. This is helpful when you want to identify folders and files where inheritance has been broken.

To include inherited permissions in the report as well, run the command with the -IncludeInheritedPermissions switch.

Generate-LibraryPermissionsReport `
-SiteURL $SiteURL `
-ListName $ListName `
-ReportFile $ReportFile `
-ScanItemLevel `
-IncludeInheritedPermissions

Use this option when you need a complete SharePoint permission inventory. Keep in mind that the CSV file can become large when the document library contains many files and folders.

Access Denied Error in PnP PowerShell

While running the script, you may encounter the following error:

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

You can see the exact error message in the screenshot below.

Access Denied Error in PnP PowerShell

This error usually occurs when the account used to connect through Connect-PnPOnline does not have sufficient access to read permissions from the SharePoint site, document library, folders, or files.

To resolve the issue, sign in with an account that has the required permissions. In many tenant-wide administrative scenarios, assigning the SharePoint Administrator role to the account can resolve the error.

You can assign the SharePoint Administrator role from the Microsoft 365 admin center:

  1. Open the Microsoft 365 admin center.
  2. Select Users and then Active users.
  3. Choose the user account.
  4. Open the Roles section.
  5. Select Admin center access.
  6. Assign the SharePoint Administrator role.
  7. Save the changes.

Here is a screenshot for your reference.

PnP PowerShell Get SharePoint Folder Permissions

After the role assignment has taken effect, run the PnP PowerShell script again.

Important Notes

  • The account running the script must have access to the site and the objects being scanned.
  • The script can retrieve permissions for document libraries as well as SharePoint lists.
  • Use -ScanItemLevel to include folders, subfolders, files, and list items.
  • Use -IncludeInheritedPermissions when you need both unique and inherited permission assignments.
  • The report excludes Limited Access permissions to make the output easier to review.
  • For very large libraries, run the report during off-peak hours and allow enough time for the scan to complete.
  • Review the CSV file in Excel and filter the HasUniquePermissions column to quickly find files and folders with broken permission inheritance.

Conclusion

Using PnP PowerShell is an efficient way to audit SharePoint folder permissions, file permissions, and item-level permissions in a SharePoint Online document library. The script gives you an exportable CSV report that clearly shows users, groups, permission levels, direct assignments, inherited access, and unique permissions.

This approach is useful for SharePoint permission audits, compliance reviews, security assessments, migration planning, and routine administration of document libraries with complex folder structures.

You may also like the following tutorials:

⏰ LIMITED-TIME OFFER

Join the SharePoint & Power Platform Developer Live Training

📅 Live training starts October 5, 2026
SharePoint Development
Power Apps & Power Automate
Copilot Studio
🎁
FREE 1-Year Access to SPGuides.Academy

Enroll now and get access to all 9 academy courses at no extra cost.

Secure your seat before the batch fills up.
Get the live training plus the complete SPGuides.Academy learning library.

Enroll Now & Get Your FREE 1-Year Academy Access → View live training details and schedule
Power Apps functions free pdf

30 Power Apps Functions

This free guide walks you through the 30 most-used Power Apps functions with real business examples, exact syntax, and results you can see.

Live Webinar

SharePoint Integration Power Apps Form With Repeating Table [Invoice Management System]

Learn how to build an invoice management system using SharePoint integration and a repeating table.

📅 2nd September 2026 – 10:00 AM EST | 7:30 PM IST

Download User registration canvas app

DOWNLOAD USER REGISTRATION POWER APPS CANVAS APP

Download a fully functional Power Apps Canvas App (with Power Automate): User Registration App