Exporting sharepoint folders and sub-folders names + permissions

Tamir Giladi - Comoz Technologies 25 Reputation points
2023-02-26T09:22:42.75+00:00

Hi team,

I have a SharePoint site with a lot of folders, sub-folders, and sub-sub-sub-folders...

Each folder has different accessibility.

I would like to export a csv file with:

  1. Folder name
  2. Folder location
  3. Member names who have access (permission) to the folder.

How may I do it?

Thanks,

Tamir

SharePoint
SharePoint
A group of Microsoft Products and technologies used for sharing and managing content, knowledge, and applications.
9,412 questions
PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
1,964 questions
{count} vote

2 answers

Sort by: Most helpful
  1. Haoyan Xue_MSFT 18,841 Reputation points Microsoft Vendor
    2023-02-28T08:26:28.7833333+00:00

    Hi @Tamir Giladi - Comoz Technologies ,

    Try to use this PnP Powershell code to generate a permission report for a given folder and all its subfolders in SharePoint Online(replace $SiteURL, $FolderSiteRelativeURL):

    #Function to Get Permissions Applied on a particular Folder  
    Function Get-PnPFolderPermission([Microsoft.SharePoint.Client.Folder]$Folder)  
    {  
        Try {  
            #Get permissions assigned to the Folder  
            Get-PnPProperty -ClientObject $Folder.ListItemAllFields -Property HasUniqueRoleAssignments, RoleAssignments  
        
            #Check if Folder has unique permissions  
            $HasUniquePermissions = $Folder.ListItemAllFields.HasUniqueRoleAssignments  
           
            #Loop through each permission assigned and extract details  
            $PermissionCollection = @()  
            Foreach($RoleAssignment in $Folder.ListItemAllFields.RoleAssignments)  
            {  
                #Get the Permission Levels assigned and Member  
                Get-PnPProperty -ClientObject $RoleAssignment -Property RoleDefinitionBindings, Member  
       
                #Leave the Hidden Permissions  
                If($RoleAssignment.Member.IsHiddenInUI -eq $False)  
                {     
                    #Get the Principal Type: User, SP Group, AD Group  
                    $PermissionType = $RoleAssignment.Member.PrincipalType  
                    $PermissionLevels = $RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name  
        
                    #Remove Limited Access  
                    $PermissionLevels = ($PermissionLevels | Where { $_ -ne "Limited Access"}) -join ","  
                    If($PermissionLevels.Length -eq 0) {Continue}  
        
                    #Get SharePoint group members  
                    If($PermissionType -eq "SharePointGroup")  
                    {  
                        #Get Group Members  
                        $GroupName = $RoleAssignment.Member.LoginName  
                        $GroupMembers = Get-PnPGroupMember -Identity $GroupName  
                        
                        #Leave Empty Groups  
                        If($GroupMembers.count -eq 0){Continue}  
                        If($GroupName -notlike "*System Account*" -and $GroupName -notlike "*SharingLinks*" -and $GroupName -notlike "*tenant*" -and $GroupName -notlike `  
                            "Excel Services Viewers" -and $GroupName -notlike "Restricted Readers" -and  $GroupName -notlike "Records Center Web Service Submitters for records")  
                        {  
                            ForEach($User in $GroupMembers)  
                            {  
                                #Add the Data to Folder  
                                $Permissions = New-Object PSObject  
                                $Permissions | Add-Member NoteProperty FolderName($Folder.Name)  
                                $Permissions | Add-Member NoteProperty FolderURL($Folder.ServerRelativeUrl)  
                                $Permissions | Add-Member NoteProperty User($User.Title)  
                                $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  
                    {  
       
                        #Add the Data to Folder  
                        $Permissions = New-Object PSObject  
                        $Permissions | Add-Member NoteProperty FolderName($Folder.Name)  
                        $Permissions | Add-Member NoteProperty FolderURL($Folder.ServerRelativeUrl)  
                        $Permissions | Add-Member NoteProperty User($RoleAssignment.Member.Title)  
                        $Permissions | Add-Member NoteProperty Type($PermissionType)  
                        $Permissions | Add-Member NoteProperty Permissions($PermissionLevels)  
                        $Permissions | Add-Member NoteProperty GrantedThrough("Direct Permissions")  
                        $PermissionCollection += $Permissions  
                    }  
                }  
            }  
            #Export Permissions to CSV File  
            $PermissionCollection | Export-CSV $ReportFile -NoTypeInformation -Append  
            Write-host -f Green "`n*** Permissions of Folder '$($Folder.Name)' at '$($Folder.ServerRelativeUrl)' Exported Successfully!***"  
        }  
        Catch {  
        write-host -f Red "Error Generating Folder Permission Report!" $_.Exception.Message  
        }  
    }  
          
    # Parameters  
    $SiteURL="https://yourdomain.sharepoint.com/sites/xyzax-version1"  
    $ReportFile="C:\FolderPermissionRpt.csv"  
    $FolderSiteRelativeURL = "/dlibrary2/folder1"  
        
    #Connect to the Site collection  
    Connect-PnPOnline -URL $SiteURL -Interactive  
       
    #Delete the file, If already exist!  
    If (Test-Path $ReportFile) { Remove-Item $ReportFile }  
       
    #Get the Folder and all Subfolders from URL  
    $Folder = Get-PnPFolder -Url $FolderSiteRelativeURL  
    $SubFolders = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderSiteRelativeURL -ItemType Folder -Recursive  
       
    #Call the function to generate folder permission report  
    Get-PnPFolderPermission $Folder  
    $SubFolders | ForEach-Object { Get-PnPFolderPermission $_ }  
    
    

    The running result is as shown below:

    User's image


    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Tamir Giladi - Comoz Technologies 25 Reputation points
    2023-03-23T13:29:52.9766667+00:00

    My solution was by using the following code:
    Importent tips:

    1. I used it on Windows Powershell instead of SharePoint Online Management Shell.
    2. Don't forget to run it as an administrator.
    3. I used https://www.sharepointdiary.com/2019/02/import-module-could-not-load-type-microsoft-sharepoint-administration-designpackagetype-from-assembly.htmlas well in order to import modules
    4. Don't forget to replace the @SiteURL
    #Function to Get Permissions Applied on a particular Object, such as: Web, List or Folder
    Function Get-PnPPermissions([Microsoft.SharePoint.Client.SecurableObject]$Object)
    {
        #Determine the type of the object
        Switch($Object.TypedObject.ToString())
        {
            "Microsoft.SharePoint.Client.Web"  { $ObjectType = "Site" ; $ObjectURL = $Object.URL; $ObjectTitle = $Object.Title }
            "Microsoft.SharePoint.Client.ListItem"
            {
                $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)
            }
            Default
            {
                $ObjectType = $Object.BaseType #List, DocumentLibrary, etc
                $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 permissions assigned to the object
        Get-PnPProperty -ClientObject $Object -Property HasUniqueRoleAssignments, RoleAssignments
      
        #Check if Object has unique permissions
        $HasUniquePermissions = $Object.HasUniqueRoleAssignments
          
        #Loop through each permission assigned and extract details
        $PermissionCollection = @()
        Foreach($RoleAssignment in $Object.RoleAssignments)
        {
            #Get the Permission Levels assigned and Member
            Get-PnPProperty -ClientObject $RoleAssignment -Property RoleDefinitionBindings, Member
      
            #Get the Principal Type: User, SP Group, AD Group
            $PermissionType = $RoleAssignment.Member.PrincipalType
         
            #Get the Permission Levels assigned
            $PermissionLevels = $RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name
      
            #Remove Limited Access
            $PermissionLevels = ($PermissionLevels | Where { $_ -ne "Limited Access"}) -join "; "
      
            #Leave Principals with no Permissions assigned
            If($PermissionLevels.Length -eq 0) {Continue}
      
            #Check if the Principal is SharePoint group
            If($PermissionType -eq "SharePointGroup")
            {
                #Get Group Members
                $GroupMembers = Get-PnPGroupMember -Identity $RoleAssignment.Member.LoginName
                      
                #Leave Empty Groups
                If($GroupMembers.count -eq 0){Continue}
                $GroupUsers = ($GroupMembers | Select -ExpandProperty Title | Where { $_ -ne "System Account"}) -join "; "
                If($GroupUsers.Length -eq 0) {Continue}
     
                #Add the Data to Object
                $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 Type($PermissionType)
                $Permissions | Add-Member NoteProperty Permissions($PermissionLevels)
                $Permissions | Add-Member NoteProperty GrantedThrough("SharePoint Group: $($RoleAssignment.Member.LoginName)")
                $PermissionCollection += $Permissions
            }
            Else #User
            {
                #Add the Data to Object
                $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 Type($PermissionType)
                $Permissions | Add-Member NoteProperty Permissions($PermissionLevels)
                $Permissions | Add-Member NoteProperty GrantedThrough("Direct Permissions")
                $PermissionCollection += $Permissions
            }
        }
        #Export Permissions to CSV File
        $PermissionCollection | Export-CSV $ReportFile -NoTypeInformation -Append
    }
        
    #Function to get sharepoint online site permissions report
    Function Generate-PnPSitePermissionRpt()
    {
    [cmdletbinding()]
     
        Param 
        (   
            [Parameter(Mandatory=$false)] [String] $SiteURL,
            [Parameter(Mandatory=$false)] [String] $ReportFile,        
            [Parameter(Mandatory=$false)] [switch] $Recursive,
            [Parameter(Mandatory=$false)] [switch] $ScanFolders,
            [Parameter(Mandatory=$false)] [switch] $IncludeInheritedPermissions
        ) 
        Try {
            #Connect to the Site
            Connect-PnPOnline -URL $SiteURL -Interactive
            #Get the Web
            $Web = Get-PnPWeb
      
            Write-host -f Yellow "Getting Site Collection Administrators..."
            #Get Site Collection Administrators
            $SiteAdmins = Get-PnPSiteCollectionAdmin
              
            $SiteCollectionAdmins = ($SiteAdmins | Select -ExpandProperty Title) -join "; "
            #Add the Data to Object
            $Permissions = New-Object PSObject
            $Permissions | Add-Member NoteProperty Object("Site Collection")
            $Permissions | Add-Member NoteProperty Title($Web.Title)
            $Permissions | Add-Member NoteProperty URL($Web.URL)
            $Permissions | Add-Member NoteProperty HasUniquePermissions("TRUE")
            $Permissions | Add-Member NoteProperty Users($SiteCollectionAdmins)
            $Permissions | Add-Member NoteProperty Type("Site Collection Administrators")
            $Permissions | Add-Member NoteProperty Permissions("Site Owner")
            $Permissions | Add-Member NoteProperty GrantedThrough("Direct Permissions")
                    
            #Export Permissions to CSV File
            $Permissions | Export-CSV $ReportFile -NoTypeInformation
        
            #Function to Get Permissions of Folders in a given List
            Function Get-PnPFolderPermission([Microsoft.SharePoint.Client.List]$List)
            {
                Write-host -f Yellow "`t `t Getting Permissions of Folders in the List:"$List.Title
                 
                #Get All Folders from List
                $ListItems = Get-PnPListItem -List $List -PageSize 2000
                $Folders = $ListItems | Where { ($_.FileSystemObjectType -eq "Folder") -and ($_.FieldValues.FileLeafRef -ne "Forms") -and (-Not($_.FieldValues.FileLeafRef.StartsWith("_")))}
     
                $ItemCounter = 0
                #Loop through each Folder
                ForEach($Folder in $Folders)
                {
                    #Get Objects with Unique Permissions or Inherited Permissions based on 'IncludeInheritedPermissions' switch
                    If($IncludeInheritedPermissions)
                    {
                        Get-PnPPermissions -Object $Folder
                    }
                    Else
                    {
                        #Check if Folder has unique permissions
                        $HasUniquePermissions = Get-PnPProperty -ClientObject $Folder -Property HasUniqueRoleAssignments
                        If($HasUniquePermissions -eq $True)
                        {
                            #Call the function to generate Permission report
                            Get-PnPPermissions -Object $Folder
                        }
                    }
                    $ItemCounter++
                    Write-Progress -PercentComplete ($ItemCounter / ($Folders.Count) * 100) -Activity "Getting Permissions of Folders in List '$($List.Title)'" -Status "Processing Folder '$($Folder.FieldValues.FileLeafRef)' at '$($Folder.FieldValues.FileRef)' ($ItemCounter of $($Folders.Count))" -Id 2 -ParentId 1
                }
            }
      
            #Function to Get Permissions of all lists from the given web
            Function Get-PnPListPermission([Microsoft.SharePoint.Client.Web]$Web)
            {
                #Get All Lists from the web
                $Lists = Get-PnPProperty -ClientObject $Web -Property Lists
        
                #Exclude system lists
                $ExcludedLists = @("Access Requests","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", "Images", "site collection images"
                ,"Master Docs","Master Page Gallery","MicroFeed","NintexFormXml","Quick Deploy Items","Relationships List","Reusable Content","Reporting Metadata", "Reporting Templates", "Search Config List","Site Assets","Preservation Hold Library",
                "Site Pages", "Solution Gallery","Style Library","Suggested Content Browser Locations","Theme Gallery", "TaxonomyHiddenList","User Information List","Web Part Gallery","wfpub","wfsvc","Workflow History","Workflow Tasks", "Pages")
                  
                $Counter = 0
                #Get all lists from the web  
                ForEach($List in $Lists)
                {
                    #Exclude System Lists
                    If($List.Hidden -eq $False -and $ExcludedLists -notcontains $List.Title)
                    {
                        $Counter++
                        Write-Progress -PercentComplete ($Counter / ($Lists.Count) * 100) -Activity "Exporting Permissions from List '$($List.Title)' in $($Web.URL)" -Status "Processing Lists $Counter of $($Lists.Count)" -Id 1
      
                        #Get Item Level Permissions if 'ScanFolders' switch present
                        If($ScanFolders)
                        {
                            #Get Folder Permissions
                            Get-PnPFolderPermission -List $List
                        }
      
                        #Get Lists with Unique Permissions or Inherited Permissions based on 'IncludeInheritedPermissions' switch
                        If($IncludeInheritedPermissions)
                        {
                            Get-PnPPermissions -Object $List
                        }
                        Else
                        {
                            #Check if List has unique permissions
                            $HasUniquePermissions = Get-PnPProperty -ClientObject $List -Property HasUniqueRoleAssignments
                            If($HasUniquePermissions -eq $True)
                            {
                                #Call the function to check permissions
                                Get-PnPPermissions -Object $List
                            }
                        }
                    }
                }
            }
        
            #Function to Get Webs's Permissions from given URL
            Function Get-PnPWebPermission([Microsoft.SharePoint.Client.Web]$Web)
            {
                #Call the function to Get permissions of the web
                Write-host -f Yellow "Getting Permissions of the Web: $($Web.URL)..."
                Get-PnPPermissions -Object $Web
        
                #Get List Permissions
                Write-host -f Yellow "`t Getting Permissions of Lists and Libraries..."
                Get-PnPListPermission($Web)
      
                #Recursively get permissions from all sub-webs based on the "Recursive" Switch
                If($Recursive)
                {
                    #Get Subwebs of the Web
                    $Subwebs = Get-PnPProperty -ClientObject $Web -Property Webs
      
                    #Iterate through each subsite in the current web
                    Foreach ($Subweb in $web.Webs)
                    {
                        #Get Webs with Unique Permissions or Inherited Permissions based on 'IncludeInheritedPermissions' switch
                        If($IncludeInheritedPermissions)
                        {
                            Get-PnPWebPermission($Subweb)
                        }
                        Else
                        {
                            #Check if the Web has unique permissions
                            $HasUniquePermissions = Get-PnPProperty -ClientObject $SubWeb -Property HasUniqueRoleAssignments
        
                            #Get the Web's Permissions
                            If($HasUniquePermissions -eq $true)
                            {
                                #Call the function recursively                           
                                Get-PnPWebPermission($Subweb)
                            }
                        }
                    }
                }
            }
      
            #Call the function with RootWeb to get site collection permissions
            Get-PnPWebPermission $Web
        
            Write-host -f Green "`n*** Site Permission Report Generated Successfully!***"
         }
        Catch {
            write-host -f Red "Error Generating Site Permission Report!" $_.Exception.Message
       }
    }
        
    #region ***Parameters***
    $SiteURL="https://tenent.sharepoint.com/sites/YourSite/"
    $ReportFile="C:\Legal-SitePermissionRpt.csv"
    #endregion
      
    #Call the function to generate permission report
    Generate-PnPSitePermissionRpt -SiteURL $SiteURL -ReportFile $ReportFile -ScanFolders
     
    #Generate-PnPSitePermissionRpt -SiteURL $SiteURL -ReportFile $ReportFile -Recursive -ScanFolders -IncludeInheritedPermissions
    
    
    #Read more: https://www.sharepointdiary.com/2019/09/sharepoint-online-user-permissions-audit-report-using-pnp-powershell.html#ixzz7wlHup8od