PowerShell – SharePoint – Permission report for all lists and libraries within every site collection and subsite

0

Here is a script that comes very handy when you need to replace some SharePoint groups with other ones. While doing so you definitely want to make sure no one has lost access. So you need to know where each group has been used.

To create this script I used Salaudeen Rajack’s PnP PowerShell to Export Document Library Permissions in SharePoint Online script posted here (https://www.sharepointdiary.com/2019/02/sharepoint-online-pnp-powershell-to-export-document-library-permissions.html), then did some adjustments to it including converting it to a function. Then added my code to go through each site collection and subsite.

What this script does and how it might be beneficial to you:

  • goes through every site collection and subsite, then library and list;
  • has a list of site collections to exclude;
  • does not include Office 365 Group sites;
  • outputs the following data – site/subsite URL, library/list title, user/group name, user/group type, permission level, how it’s granted.

This script might take hours if you have lots of site collections and/or subsites.

#--------------------------------------[Variables]--------------------------------------
$AdminSiteUrl = "https://contoso-admin.sharepoint.com/"

$Exclusions = @(
    "https://contoso.sharepoint.com/portals/hub",
    "https://contoso-my.sharepoint.com/",
    "https://contoso.sharepoint.com/portals/Community",
    "https://contoso.sharepoint.com/sites/dev",
    "https://contoso.sharepoint.com/search"
)

$OutputFile = "C:\Temp\AllPermissions.csv"
#-------------------------------------[Function 1]--------------------------------------
Function Get-AllPermissions {
    [CmdletBinding(DefaultParameterSetName="MainSiteSet")]

    param (
        [Parameter(ParameterSetName="MainSiteSet", Mandatory=$True)] $Title,
        [Parameter(ParameterSetName="SubsiteSet", Mandatory=$True)] $SubsiteUrl,
        [Parameter(ParameterSetName="SubsiteSet", Mandatory=$True)] $SubsiteTitle
    )

    Begin{}

    Process{
        # Get the document library depending if it's within a main Site in the Site Collection or Subsite
        If ($PSCmdlet.ParameterSetName -eq "MainSiteSet") {
            $Library = Get-PnpList -Identity $Title -Includes RoleAssignments
        }
        Else {
            $Library = Get-PnpList -Identity $SubsiteTitle -Web $SubsiteUrl -Includes RoleAssignments
        }
 
        # Get all users and groups who has access
        $RoleAssignments = $Library.RoleAssignments
        $PermissionCollection = @()
        Foreach ($RoleAssignment in $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
            $PermissionLevels = $RoleAssignment.RoleDefinitionBindings | Select -ExpandProperty Name
     
            #Get all permission levels assigned (Excluding: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
                $GroupMembers = Get-PnPGroupMembers -Identity $RoleAssignment.Member.LoginName
            
                #Leave Empty Groups
                If($GroupMembers.count -eq 0){Continue}
 
                ForEach($User in $GroupMembers) {
                    $outObject = "" | Select Site,Title,User,Type,Permissions,GrantedThrough
                    $outObject."Site" = If ($PSCmdlet.ParameterSetName -eq "MainSiteSet") {
                        $SiteCollection.URL
                    }
                    Else {
                        $Subsite.Url
                    }
                    $outObject."Title" = $Library.Title
                    $outObject."User" = $User.Title
                    $outObject."Type" = $PermissionType
                    $outObject."Permissions" = $PermissionLevels
                    $outObject."GrantedThrough" = "SharePoint Group: $($RoleAssignment.Member.LoginName)"
                    $PermissionCollection += $outObject
                }
            }
            Else {
                $outObject = "" | Select Site,Title,User,Type,Permissions,GrantedThrough
                $outObject."Site" = If ($PSCmdlet.ParameterSetName -eq "MainSiteSet") {
                    $SiteCollection.URL
                }
                Else {
                    $Subsite.Url
                }
                $outObject."Title" = $Library.Title
                $outObject."User" = $RoleAssignment.Member.Title
                $outObject."Type" = $PermissionType
                $outObject."Permissions" = $PermissionLevels
                $outObject."GrantedThrough" = "Direct Permissions"
                $PermissionCollection += $outObject
            }
        }
        $PermissionCollection
    }

    End{}

}
#---------------------------------------------------------------------------------------
# Start timer
$elapsed = [System.Diagnostics.Stopwatch]::StartNew()

# Connect to SharePoint Online Admin
Connect-PnPOnline -Url $AdminSiteUrl -Credentials $UserCredential

# Get all Site Collections that are not Office 365 Group Site Collections and not in the Exclusion List
$SiteCollections = Get-SPOSite | Where-Object {($Exclusions -cnotcontains $_.Url) -and ($_.Template -ne "GROUP#0")}

Foreach ($SiteCollection in $SiteCollections) {

    # Connect to each site collection
    Connect-PnPOnline -Url $SiteCollection.Url -Credentials $UserCredential

    # Get libraries within the main site of the site collection
    $ListsAndLibraries = Get-PnPList
    $AllPermissionsCollection = @()
    Foreach ($ListAndLibrary in $ListsAndLibraries) {
        Write-Host "Processing" $ListAndLibrary.RootFolder.ServerRelativeUrl.Substring(1) -ForegroundColor Yellow
        $Permissions = Get-AllPermissions -Title $ListAndLibrary.Title
        $AllPermissionsCollection += $Permissions
    }
    
    # Get all subsites
    $Subsites = Get-PnPSubWebs -Recurse 
    foreach ($Subsite in $Subsites) {
        $ListsAndLibraries = Get-PnPList -Web $Subsite.ServerRelativeUrl
        Foreach ($ListAndLibrary in $ListsAndLibraries) {
            Write-host $ListAndLibrary.Url
            Write-Host "Processing" $ListAndLibrary.RootFolder.ServerRelativeUrl.Substring(1) -ForegroundColor Yellow
            $Permissions = Get-AllPermissions -SubsiteTitle $ListAndLibrary.Title -SubsiteUrl $Subsite.ServerRelativeUrl
            $AllPermissionsCollection += $Permissions
        }
    }
    $AllSitesPermissionsCollection += $AllPermissionsCollection
}

# Export results to CSV
$AllSitesPermissionsCollection | Export-CSV $OutputFile -NoTypeInformation
Write-host "Done!" -ForegroundColor Green

# End Timer
Write-Host "Total Time: $($elapsed.Elapsed.ToString())"

 

0

Leave a Reply