SharePoint Online: Site Collection Permissions Report using PowerShell

Requirement: Generate permissions report for a SharePoint Online site collection.

SharePoint Online: Site Collection Permissions Report using PowerShell

Have you ever wanted to get SharePoint Online Site and subsites permissions using PowerShell? Well, This PowerShell script generates a permission report on all objects which has unique permissions on the given site collection. It scans through the following securables:

  • Site collection administrators group
  • Given site collection and sub-sites with unique permissions
  • All lists and libraries with unique permissions
  • All list items (and folders) with unique permissions.
You must add the account that runs this PowerShell Scripts as “Site Collection Administrator” to all sites!
How to Add Site Collection Administrator to All SharePoint Online Sites?

Here is the SharePoint Online PowerShell to get the site permissions report:

#sharepoint online powershell permissions report
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"
  
#To call a non-generic method Load
Function Invoke-LoadMethod() {
    param(
            [Microsoft.SharePoint.Client.ClientObject]$Object = $(throw "Please provide a Client Object"),
            [string]$PropertyName
        ) 
   $ctx = $Object.Context
   $load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load") 
   $type = $Object.GetType()
   $clientLoad = $load.MakeGenericMethod($type)
  
   $Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name)
   $Expression = [System.Linq.Expressions.Expression]::Lambda([System.Linq.Expressions.Expression]::Convert([System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$PropertyName),[System.Object] ), $($Parameter))
   $ExpressionArray = [System.Array]::CreateInstance($Expression.GetType(), 1)
   $ExpressionArray.SetValue($Expression, 0)
   $clientLoad.Invoke($ctx,@($Object,$ExpressionArray))
}
 
#Function to Get Permissions Applied on a particular Object, such as: Web, List or Item
Function Get-Permissions([Microsoft.SharePoint.Client.SecurableObject]$Object)
{
    #Determine the type of the object
    Switch($Object.TypedObject.ToString())
    {
        "Microsoft.SharePoint.Client.Web"  { $ObjectType = "Site" ; $ObjectURL = $Object.URL }
        "Microsoft.SharePoint.Client.ListItem"
        { 
            $ObjectType = "List Item"
            #Get the URL of the List Item
            Invoke-LoadMethod -Object $Object.ParentList -PropertyName "DefaultDisplayFormUrl"
            $Ctx.ExecuteQuery()
            $DefaultDisplayFormUrl = $Object.ParentList.DefaultDisplayFormUrl
            $ObjectURL = $("{0}{1}?ID={2}" -f $Ctx.Web.Url.Replace($Ctx.Web.ServerRelativeUrl,''), $DefaultDisplayFormUrl,$Object.ID)
        }
        Default 
        { 
            $ObjectType = "List/Library"
            #Get the URL of the List or Library
            $Ctx.Load($Object.RootFolder)
            $Ctx.ExecuteQuery()            
            $ObjectURL = $("{0}{1}" -f $Ctx.Web.Url.Replace($Ctx.Web.ServerRelativeUrl,''), $Object.RootFolder.ServerRelativeUrl)
        }
    }
 
    #Get permissions assigned to the object
    $Ctx.Load($Object.RoleAssignments)
    $Ctx.ExecuteQuery()
 
    Foreach($RoleAssignment in $Object.RoleAssignments)
    { 
                $Ctx.Load($RoleAssignment.Member)
                $Ctx.executeQuery()
                 
                #Get the Permissions on the given object
                [email protected]()
                $Ctx.Load($RoleAssignment.RoleDefinitionBindings)
                $Ctx.ExecuteQuery()
                Foreach ($RoleDefinition in $RoleAssignment.RoleDefinitionBindings)
                {
                    $Permissions += $RoleDefinition.Name +";"
                }
 
                #Check direct permissions
                if($RoleAssignment.Member.PrincipalType -eq "User")
                {
                        #Send the Data to Report file
                        "$($ObjectURL) `t $($ObjectType) `t $($Object.Title)`t $($RoleAssignment.Member.LoginName) `t User `t $($Permissions)" | Out-File $ReportFile -Append
                }
                 
                ElseIf($RoleAssignment.Member.PrincipalType -eq "SharePointGroup")
                {        
                        #Send the Data to Report file
                        "$($ObjectURL) `t $($ObjectType) `t $($Object.Title)`t $($RoleAssignment.Member.LoginName) `t SharePoint Group `t $($Permissions)" | Out-File $ReportFile -Append
                }
                ElseIf($RoleAssignment.Member.PrincipalType -eq "SecurityGroup")
                {
                    #Send the Data to Report file
                    "$($ObjectURL) `t $($ObjectType) `t $($Object.Title)`t $($RoleAssignment.Member.Title)`t $($Permissions) `t Security Group" | Out-File $ReportFile -Append
                }
    }
}
 
#powershell to get sharepoint online site permissions
Function Generate-SPOSitePermissionRpt($SiteURL,$ReportFile)
{
    Try {
        #Get Credentials to connect
        $Cred= Get-Credential
        $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
  
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Credentials
 
        #Get the Web
        $Web = $Ctx.Web
        $Ctx.Load($Web)
        $Ctx.ExecuteQuery()
 
        #Write CSV- TAB Separated File) Header
        "URL `t Object `t Title `t Account `t PermissionType `t Permissions" | out-file $ReportFile
 
        Write-host -f Yellow "Getting Site Collection Administrators..."
        #Get Site Collection Administrators
        $SiteUsers= $Ctx.Web.SiteUsers 
        $Ctx.Load($SiteUsers)
        $Ctx.ExecuteQuery()
        $SiteAdmins = $SiteUsers | Where { $_.IsSiteAdmin -eq $true}
 
        ForEach($Admin in $SiteAdmins)
        {
            #Send the Data to report file
            "$($Web.URL) `t Site Collection `t $($Web.Title)`t $($Admin.Title) `t Site Collection Administrator `t  Site Collection Administrator" | Out-File $ReportFile -Append
        }
 
        #Function to Get Permissions of All List Items of a given List
        Function Get-SPOListItemsPermission([Microsoft.SharePoint.Client.List]$List)
        {
            Write-host -f Yellow "`t `t Getting Permissions of List Items in the List:"$List.Title

            $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
            $Query.ViewXml = "<View Scope='RecursiveAll'><Query><OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy></Query><RowLimit Paged='TRUE'>$BatchSize</RowLimit></View>"

            $Counter = 0
            #Batch process list items - to mitigate list threshold issue on larger lists
            Do {  
                #Get 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)
                {
                    Invoke-LoadMethod -Object $ListItem -PropertyName "HasUniqueRoleAssignments"
                    $Ctx.ExecuteQuery()
                    If($ListItem.HasUniqueRoleAssignments -eq $True)
                    {
                        #Call the function to generate Permission report
                        Get-Permissions -Object $ListItem
                    }
                    $Counter++
                    Write-Progress -PercentComplete ($Counter / ($List.ItemCount) * 100) -Activity "Processing Items $Counter of $($List.ItemCount)" -Status "Searching Unique Permissions in List Items of '$($List.Title)'" 
                }
            } While ($Query.ListItemCollectionPosition -ne $null)
        }
 
        #Function to Get Permissions of all lists from the web
        Function Get-SPOListPermission([Microsoft.SharePoint.Client.Web]$Web)
        {
            #Get All Lists from the web
            $Lists = $Web.Lists
            $Ctx.Load($Lists)
            $Ctx.ExecuteQuery()
 
            #Get all lists from the web   
            ForEach($List in $Lists)
            {
                #Exclude System Lists
                If($List.Hidden -eq $False)
                {
                    #Get List Items Permissions
                    Get-SPOListItemsPermission $List
 
                    #Get the Lists with Unique permission
                    Invoke-LoadMethod -Object $List -PropertyName "HasUniqueRoleAssignments"
                    $Ctx.ExecuteQuery()
 
                    If( $List.HasUniqueRoleAssignments -eq $True)
                    {
                        #Call the function to check permissions
                        Get-Permissions -Object $List
                    }
                }
            }
        }
 
        #Function to Get Webs's Permissions from given URL
        Function Get-SPOWebPermission([Microsoft.SharePoint.Client.Web]$Web) 
        {
            #Get all immediate subsites of the site
            $Ctx.Load($web.Webs)  
            $Ctx.executeQuery()
  
            #Call the function to Get Lists of the web
            Write-host -f Yellow "Getting the Permissions of Web "$Web.URL"..."
 
            #Check if the Web has unique permissions
            Invoke-LoadMethod -Object $Web -PropertyName "HasUniqueRoleAssignments"
            $Ctx.ExecuteQuery()
 
            #Get the Web's Permissions
            If($web.HasUniqueRoleAssignments -eq $true) 
            { 
                Get-Permissions -Object $Web
            }
 
            #Scan Lists with Unique Permissions
            Write-host -f Yellow "`t Getting the Permissions of Lists and Libraries in "$Web.URL"..."
            Get-SPOListPermission($Web)
  
            #Iterate through each subsite in the current web
            Foreach ($Subweb in $web.Webs)
            {
                 #Call the function recursively                            
                 Get-SPOWebPermission($SubWeb)
            }
        }
 
        #Call the function with RootWeb to get site collection permissions
        Get-SPOWebPermission $Web
 
        Write-host -f Green "Site Permission Report Generated Successfully!"
     }
    Catch {
        write-host -f Red "Error Generating Site Permission Report!" $_.Exception.Message
   }
}
 
#Set parameter values
$SiteURL="https://crescent.sharepoint.com"
$ReportFile="C:\Temp\SitePermissionRpt.csv"
$BatchSize = 500
 
#Call the function
Generate-SPOSitePermissionRpt -SiteURL $SiteURL -ReportFile $ReportFile

Output Report of the script:
The above script generates a CSV file in the provided ReportFile parameter. Here is a sample report generated.

sharepoint online site collection permission report using powershell

If you are looking for a permission report for a specific user, use my another script: SharePoint Online: User Permissions Report using PowerShell

Update: SharePoint Online Site Permission Report V2

How about extending the script to expand SharePoint Groups (instead of just group name, have all members of the group) and introduce switches for Recursively process all sub-sites, Scan up to Item level permissions and export all permissions including the one with inheriting permissions from its parent? Here is the SharePoint Online PowerShell to get all user permissions:

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 call a non-generic method Load
Function Invoke-LoadMethod([Microsoft.SharePoint.Client.ClientObject]$Object = $(throw "Please provide a Client Object"),[string]$PropertyName) 
{
   $Ctx = $Object.Context
   $Load = [Microsoft.SharePoint.Client.ClientContext].GetMethod("Load") 
   $Type = $Object.GetType()
   $ClientLoad = $load.MakeGenericMethod($type)
   
   $Parameter = [System.Linq.Expressions.Expression]::Parameter(($type), $type.Name)
   $Expression = [System.Linq.Expressions.Expression]::Lambda([System.Linq.Expressions.Expression]::Convert([System.Linq.Expressions.Expression]::PropertyOrField($Parameter,$PropertyName),[System.Object] ), $($Parameter))
   $ExpressionArray = [System.Array]::CreateInstance($Expression.GetType(), 1)
   $ExpressionArray.SetValue($Expression, 0)
   $ClientLoad.Invoke($ctx,@($Object,$ExpressionArray))
}
  
#Function to Get Permissions Applied on a particular Object, such as: Web or List
Function Get-Permissions([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"
        { 
            If($Object.FileSystemObjectType -eq "Folder")
            {
                $ObjectType = "Folder"
                #Get the URL of the Folder
                Invoke-LoadMethod -Object $Object -PropertyName "Folder"
                $Ctx.ExecuteQuery()
                $ObjectTitle = $Object.Folder.Name
                $ObjectURL = $("{0}{1}" -f $Ctx.Web.Url.Replace($Ctx.Web.ServerRelativeUrl,''),$Object.Folder.ServerRelativeUrl)
            }
            Else #File or List Item
            {
                #Get the URL of the Object
                Invoke-LoadMethod -Object $Object -PropertyName "File"
                $Ctx.ExecuteQuery()
                If($Object.File.Name -ne $Null)
                {
                    $ObjectType = "File"
                    $ObjectTitle = $Object.File.Name
                    $ObjectURL = $("{0}{1}" -f $Ctx.Web.Url.Replace($Ctx.Web.ServerRelativeUrl,''),$Object.File.ServerRelativeUrl)
                }
                else
                {
                    $ObjectType = "List Item"
                    $ObjectTitle = $Object["Title"]
                    #Get the URL of the List Item
                    Invoke-LoadMethod -Object $Object.ParentList -PropertyName "DefaultDisplayFormUrl"
                    $Ctx.ExecuteQuery()
                    $DefaultDisplayFormUrl = $Object.ParentList.DefaultDisplayFormUrl
                    $ObjectURL = $("{0}{1}?ID={2}" -f $Ctx.Web.Url.Replace($Ctx.Web.ServerRelativeUrl,''), $DefaultDisplayFormUrl,$Object.ID)
                }
            }
        }
        Default 
        { 
            $ObjectType = "List or Library"
            $ObjectTitle = $Object.Title
            #Get the URL of the List or Library
            $Ctx.Load($Object.RootFolder)
            $Ctx.ExecuteQuery()            
            $ObjectURL = $("{0}{1}" -f $Ctx.Web.Url.Replace($Ctx.Web.ServerRelativeUrl,''), $Object.RootFolder.ServerRelativeUrl)
        }
    }
  
    #Check if Object has unique permissions
    Invoke-LoadMethod -Object $Object -PropertyName "HasUniqueRoleAssignments"
    $Ctx.ExecuteQuery()
    $HasUniquePermissions = $Object.HasUniqueRoleAssignments
  
    #Get permissions assigned to the object
    $RoleAssignments = $Object.RoleAssignments
    $Ctx.Load($RoleAssignments)
    $Ctx.ExecuteQuery()
   
    #Loop through each permission assigned and extract details
    $PermissionCollection = @()
    Foreach($RoleAssignment in $RoleAssignments)
    { 
        $Ctx.Load($RoleAssignment.Member)
        $Ctx.executeQuery()
   
        #Get the Principal Type: User, SP Group, AD Group
        $PermissionType = $RoleAssignment.Member.PrincipalType
   
        #Get the Permission Levels assigned
        $Ctx.Load($RoleAssignment.RoleDefinitionBindings)
        $Ctx.ExecuteQuery()
        $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
            $Group = $Ctx.web.SiteGroups.GetByName($RoleAssignment.Member.LoginName)
            $Ctx.Load($Group)
            $GroupMembers= $Group.Users
            $Ctx.Load($GroupMembers)
            $Ctx.ExecuteQuery()
            If($GroupMembers.count -eq 0){Continue}
            $GroupUsers = ($GroupMembers | Select -ExpandProperty Title) -join ","

            #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
        {
            #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-SPOSitePermissionRpt()
{    
[cmdletbinding()]

    Param  
    (    
        [Parameter(Mandatory=$false)] [String] $SiteURL, 
        [Parameter(Mandatory=$false)] [String] $ReportFile,         
        [Parameter(Mandatory=$false)] [switch] $Recursive,
        [Parameter(Mandatory=$false)] [switch] $ScanItemLevel,
        [Parameter(Mandatory=$false)] [switch] $IncludeInheritedPermissions        
    )  
    Try {
        #Get Credentials to connect
        $Cred= Get-Credential
   
        #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 & Root Web
        $Web = $Ctx.Web
        $RootWeb = $Ctx.Site.RootWeb
        $Ctx.Load($Web)
        $Ctx.Load($RootWeb)
        $Ctx.ExecuteQuery()
  
        Write-host -f Yellow "Getting Site Collection Administrators..."
        #Get Site Collection Administrators
        $SiteUsers= $RootWeb.SiteUsers 
        $Ctx.Load($SiteUsers)
        $Ctx.ExecuteQuery()
        $SiteAdmins = $SiteUsers | Where { $_.IsSiteAdmin -eq $true}
        
        $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($RootWeb.Title)
        $Permissions | Add-Member NoteProperty URL($RootWeb.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 All List Items of a given List
        Function Get-SPOListItemsPermission([Microsoft.SharePoint.Client.List]$List)
        {
            Write-host -f Yellow "`t `t Getting Permissions of List Items in the List:"$List.Title
 
            $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
            $Query.ViewXml = "<View Scope='RecursiveAll'><Query><OrderBy><FieldRef Name='ID' Ascending='TRUE'/></OrderBy></Query><RowLimit Paged='TRUE'>$BatchSize</RowLimit></View>"
 
            $ItemCounter = 0
            #Batch process list items - to mitigate list threshold issue on larger lists
            Do {  
                #Get 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)
                {
                    #Get Objects with Unique Permissions or Inherited Permissions based on 'IncludeInheritedPermissions' switch
                    If($IncludeInheritedPermissions)
                    {
                        Get-Permissions -Object $ListItem
                    }
                    Else
                    {
                        Invoke-LoadMethod -Object $ListItem -PropertyName "HasUniqueRoleAssignments"
                        $Ctx.ExecuteQuery()
                        If($ListItem.HasUniqueRoleAssignments -eq $True)
                        {
                            #Call the function to generate Permission report
                            Get-Permissions -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)'"
                }
            } While ($Query.ListItemCollectionPosition -ne $null)
        }

        #Function to Get Permissions of all lists from the web
        Function Get-SPOListPermission([Microsoft.SharePoint.Client.Web]$Web)
        {
            #Get All Lists from the web
            $Lists = $Web.Lists
            $Ctx.Load($Lists)
            $Ctx.ExecuteQuery()
  
            #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 "Processing Lists $Counter of $($Lists.Count) in $($Web.URL)" -Status "Exporting Permissions from List '$($List.Title)'"

                    #Get Item Level Permissions if 'ScanItemLevel' switch present
                    If($ScanItemLevel)
                    {
                        #Get List Items Permissions
                        Get-SPOListItemsPermission -List $List
                    }

                    #Get Lists with Unique Permissions or Inherited Permissions based on 'IncludeInheritedPermissions' switch
                    If($IncludeInheritedPermissions)
                    {
                        Get-Permissions -Object $List
                    }
                    Else
                    {
                        #Check if List has unique permissions
                        Invoke-LoadMethod -Object $List -PropertyName "HasUniqueRoleAssignments"
                        $Ctx.ExecuteQuery()
                        If($List.HasUniqueRoleAssignments -eq $True)
                        {
                            #Call the function to check permissions
                            Get-Permissions -Object $List
                        }
                    }
                }
            }
        }
  
        #Function to Get Web's Permissions from given URL
        Function Get-SPOWebPermission([Microsoft.SharePoint.Client.Web]$Web) 
        {
            #Get all immediate subsites of the site
            $Ctx.Load($web.Webs)  
            $Ctx.executeQuery()
   
            #Call the function to Get permissions of the web
            Write-host -f Yellow "Getting Permissions of the Web: $($Web.URL)..."  
            Get-Permissions -Object $Web
  
            #Get List Permissions
            Write-host -f Yellow "`t Getting Permissions of Lists and Libraries..."
            Get-SPOListPermission($Web)

            #Recursively get permissions from all sub-webs based on the "Recursive" Switch
            If($Recursive)
            {
                #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-SPOWebPermission($Subweb)
                    }
                    Else
                    {
                        #Check if the Web has unique permissions
                        Invoke-LoadMethod -Object $Subweb -PropertyName "HasUniqueRoleAssignments"
                        $Ctx.ExecuteQuery()
  
                        #Get the Web's Permissions
                        If($Subweb.HasUniqueRoleAssignments -eq $true) 
                        { 
                            #Call the function recursively                            
                            Get-SPOWebPermission($Subweb)
                        }
                    }
                }
            }
        }
  
        #Call the function with RootWeb to get site collection permissions
        Get-SPOWebPermission $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://crescent.sharepoint.com/sites/marketing"
$ReportFile="C:\Temp\SitePermissionRpt.csv"
$BatchSize = 500
#endregion

#Call the function to generate permission report
Generate-SPOSitePermissionRpt -SiteURL $SiteURL -ReportFile $ReportFile
#Generate-SPOSitePermissionRpt -SiteURL $SiteURL -ReportFile $ReportFile -Recursive -ScanItemLevel -IncludeInheritedPermissions

This script produces output as below! It gets SharePoint Online site and subsites along with its child object permission using PowerShell

SharePoint Online Site Permission Report

Salaudeen Rajack

Salaudeen Rajack is a SharePoint Architect with Two decades of SharePoint Experience. He loves sharing his knowledge and experiences with the SharePoint community, through his real-world articles!

91 thoughts on “SharePoint Online: Site Collection Permissions Report using PowerShell

  • July 7, 2021 at 9:42 PM

    I’ve tried your v1 script but I am getting an error – Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The underlying connection was closed: An unexpected error occurred on a send.”.

    It seems to occur on line 102.

    Reply
  • May 3, 2021 at 10:11 AM

    Hello Salaudeen,

    Thank you for the script that you have made. I am able to run the script, it runs successfully and generates the output in CSV file. But the results seems to incomplete. It doesn’t go through and fetch details for all the lists and libraries..

    Any suggestion why it doesn’t fetch details of other list and libraries.

    Reply
  • April 24, 2021 at 1:36 AM

    To anyone: I was running the script with no issues, until a couple of weeks ago. It is randomly stopping with the following error:

    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The remote server returned an error: (400) Bad Request.”

    Seems to be a throttling issue with Microsoft, but can’t confirm. I went through all the comments and even tried the Start-Sleep -Seconds 1.5

    Any ideas?

    Reply
  • March 22, 2021 at 8:52 PM

    Hi Salaudeen, Thanks for the great script. Even after using ScanItemLevel switch and -Recursive -IncludeInheritedPermissions. Still I am not able to get the permissions for each files in the site. I am getting output generated only for subsites. Please assist me with this.

    Reply
  • March 10, 2021 at 11:18 PM

    The second script does not work to recursively pull subitemslistssites… etc.. The first script does work however, it is very slow as it iterates through all items. Wondering if it would be better to somehow get the broken inheritance list from the permissions page first, and so all you have to iterate throgh is the main site, any itenmssubitems that are known to have differedbroken inheritance. Should cut processing time in half. Furthermore it may be better to run script 1 first, then process the result as a psobject to replace group names with its membersusers.

    Reply
  • December 16, 2020 at 3:10 PM

    I’m getting the same.

    Reply
  • December 4, 2020 at 8:48 AM

    The script was working before, but I getting the below error

    Getting Site Collection Administrators…
    Getting the Permissions of Web https://xxxx.sharepoint.com/sites/xxxx …
    Getting the Permissions of Lists and Libraries in https://xxxx.sharepoint.com/xxxx …
    Getting Permissions of List Items in the List: Calendar
    Getting Permissions of List Items in the List: Documents
    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “Exception from HRESULT: 0x80131904”

    Reply
  • November 24, 2020 at 9:38 AM

    hi,

    instead of showing the user display name, can we show the user email address?

    Reply
  • November 19, 2020 at 4:38 PM

    hi, how do i run this to include folders and subfolders?

    Reply
  • October 8, 2020 at 8:55 PM

    Can you add more than one site to the script. I have a location with 60 sites that I need to run permissions for?

    Reply
  • July 27, 2020 at 6:13 PM

    I keep getting this error unfortunately.

    Error Getting List Permissions! Exception calling “ExecuteQuery” with “0” argument(s): “‘center’ is an unexpected
    token. The expected token is ‘”‘ or ”’. Line 7, position 12.”

    Reply
  • July 17, 2020 at 4:44 PM

    I get the following error:
    Get-PnPPermissions : Cannot process argument transformation on parameter ‘Object’. Cannot convert the “Microsoft.SharePoint.Client.ListItem” value of type “Microsoft.SharePoint.Client.ListItem” to
    type “Microsoft.SharePoint.Client.SecurableObject”.

    Reply
    • October 22, 2020 at 9:31 AM

      Hi! Any solution on this?

      Reply
    • December 2, 2020 at 1:19 PM

      Try:
      1. Remove the SharePoint CSOM assemblies from GAC (Go to: C:WindowsMicrosoft.NETassemblyGAC_MSIL, Remove all Folders starting with name: Microsoft.SharePoint*)

      2. Restart your machine, and Re-install SharePoint Online PowerShell module using “Install-Module -Name Microsoft.Online.SharePoint.PowerShell”

      Reply
  • June 29, 2020 at 11:21 AM

    Thanks heaps for this however how do you remove documents being scanned as part of this? I just need to check permissions on folders only so it won’t reach the 5000 limit if I am just checking it.

    Reply
  • June 4, 2020 at 12:25 PM

    We’re getting the below:

    Getting Site Collection Administrators…
    Getting Permissions of the Web: https://XXXXXXXXXXXXXXX.sharepoint.com…
    Getting Permissions of Lists and Libraries…
    Getting Permissions of List Items in the List: AAAA
    Getting Permissions of List Items in the List: BBBB
    Getting Permissions of List Items in the List: CCCC
    Getting Permissions of List Items in the List: DDDD
    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The remote server returned an error: (429).”

    Tried implementing the fix mentioned above: “i ended up implementing this http://fangdahai.blogspot.com/2018/02/how-to-handle-429-error-in-powershell.html to get it to run reliably for me.” – It got further than the previous attempt but the Excel doc is only getting to around 6000 odd lines (just under 5000 odd before the fix was applied).

    So I now have the following in PowerShell (where >> indicated added lines)

    #Function to Get Permissions Applied on a particular Object, such as: Web or List
    Function Get-Permissions([Microsoft.SharePoint.Client.SecurableObject]$Object)
    {
        #Determine the type of the object
    >> for($retryAttempts=0; $retryAttempts -lt $Global:_retryCount; $retryAttempts++){
    >> Try{
    >> $ctx.ExecuteQuery()
    >> break
    >> }
    >> Catch [system.exception]{
    >> Start-Sleep -s $Global:_retryInterval
    >> }
    >>}
    Switch($Object.TypedObject.ToString())

    Any ideas? I’ve now trying by using the following values at the top of the script:
    $Global:_retryCount = 10000 (was 1000)
    $Global:_retryInterval = 15 (was 10)

    Reply
    • June 4, 2020 at 3:16 PM

      As above I tried with these values:
      $Global:_retryCount = 10000 (was 1000)
      $Global:_retryInterval = 15 (was 10)

      It got slightly further, but not that much, started the next list but did not complete and produced the same error message, any ideas?

      Reply
    • November 20, 2020 at 8:49 PM

      I had the 429 error. The script would crash out with this error due to what seems to be the number of request for the SharePoint server to handle. I tried above fix, the script went a little bit further but crashed out again. I then added a sleep snippet in the code which seemed to fix the issue. The script took longer to run though:
      Code; (> added new code):

      Function Get-Permissions([Microsoft.SharePoint.Client.SecurableObject]$Object)
      {
      > Start-Sleep -Seconds 1.5
      #Determine the type of the object
      for($retryAttempts=0; $retryAttempts -lt $Global:_retryCount; $retryAttempts++)

      ———-
      I’m no expert but I believe it helped the SharePoint server deal with the number of request better.

      Reply
  • May 4, 2020 at 3:50 PM

    Hi Salaudeen, i can’t seem to be able to run this for sites, subsites libraries and folders all at once. i’m having to enter each url separately. any ideas?

    Reply
    • May 6, 2020 at 5:28 PM

      Use -Recursive and -IncludeInheritedPermissions switches. E.g.
      Generate-SPOSitePermissionRpt -SiteURL $SiteURL -ReportFile $ReportFile -Recursive -IncludeInheritedPermissions

      Reply
  • April 28, 2020 at 2:45 PM

    i ended up implementing this http://fangdahai.blogspot.com/2018/02/how-to-handle-429-error-in-powershell.html to get it to run reliably for me.

    Reply
  • April 25, 2020 at 3:47 PM

    I’m getting a lot of these errors. I’m running using Recursive and scanitemlevel: Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The operation has timed out” and Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The remote server returned an error: (503) Server Unavailable.”

    Reply
  • April 10, 2020 at 10:27 AM

    I am getting this error, could you please help:

    Add-Type : Cannot bind parameter ‘Path’ to the target. Exception setting “Path”: “Cannot find path ‘C:Program
    FilesCommon FilesMicrosoft SharedWeb Server Extensions16ISAPIMicrosoft.SharePoint.Client.dll’ because it does
    not exist.”
    At C:pradeepSPOsitepermission.ps1:1 char:16
    + … -Type -Path “C:Program FilesCommon FilesMicrosoft SharedWeb Serve …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : WriteError: (:) [Add-Type], ParameterBindingException
    + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.PowerShell.Commands.AddTypeCommand

    Add-Type : Cannot bind parameter ‘Path’ to the target. Exception setting “Path”: “Cannot find path ‘C:Program
    FilesCommon FilesMicrosoft SharedWeb Server Extensions16ISAPIMicrosoft.SharePoint.Client.Runtime.dll’ because it
    does not exist.”
    At C:pradeepSPOsitepermission.ps1:2 char:16
    + … -Type -Path “C:Program FilesCommon FilesMicrosoft SharedWeb Serve …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : WriteError: (:) [Add-Type], ParameterBindingException
    + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.PowerShell.Commands.AddTypeCommand

    cmdlet Get-Credential at command pipeline position 1
    Supply values for the following parameters:
    Credential
    Error Generating Site Permission Report! Cannot find type [Microsoft.SharePoint.Client.ClientContext]: verify that the assembly containing this type is loaded.

    Reply
  • April 8, 2020 at 5:44 PM

    I’ve run the script 2 times. Once with Recursive and once without. Each time it appears to hang on the same List in a subsite. It was hanging for 3 hours this morning before I cancelled it. I was Not doing ScanItemLevel permissions. Could it be because there are a lot of items in the document library? It says Exporting Permissions from List ‘Site Collection Documents’ and hangs there.

    Reply
  • April 7, 2020 at 6:13 PM

    Is this script supposed to report on subsites when given a site collection? It only works at whatever site is requested and not its sub sites.

    Reply
    • April 7, 2020 at 8:26 PM

      This script gets permission only for given web – When you don’t use -Recursive switch or when the subsites are inheriting permissions!

      Reply
  • March 23, 2020 at 7:56 PM

    Hello,
    This script worked great! I was wondering if you had a script that adds the users email address as well?

    Reply
    • March 24, 2020 at 11:33 AM

      Use: $GroupUsersEmails = ($GroupMembers | Select -ExpandProperty Email) -join “,”

      Reply
  • March 5, 2020 at 5:15 PM

    Hi,

    Thanks for writing the script!

    I am running v2 script but seem to not be able to report on unique folder and file permissions that sit within a document library. I am only getting reports for the top level of the site. I have tried using the recursive switch amongst others but does not appear to be working.

    Do you know how i can get the script to include all files and folders that have unique permissions like it shows in the print screen.

    Many Thanks,

    Sean

    Reply
    • April 14, 2020 at 9:56 PM

      You have to use the -ScanItemLevel switch. You can see the switches and parameters that are available at the very bottom of the script.

      Reply
  • March 3, 2020 at 1:12 AM

    Hi. Script gives me this error:

    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The remote server returned an error: (401) Unauthorized.”

    Any idea why? The user is a member of Sharepoint Administrators

    Reply
  • February 5, 2020 at 7:32 AM

    Hi Salaudeen, Thanks for the great script. Unfortunately, I am unable to fetch the permissions Recursively get permissions from all sub-webs. Can you please look in to this once and let me know.

    Reply
    • February 6, 2020 at 1:25 PM

      The first Script doesn’t get objects with Inherited permissions. In V2, include switches -Recursive -IncludeInheritedPermissions.

      Reply
    • February 13, 2020 at 7:28 PM

      Thank you! I am able to connect to SPO, however not sure how to use it with your above script to pull a detailed permission report. I replaced these two lines in the script:

      $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
      $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName, $Cred.Password)

      with:

      $authManager = New-Object OfficeDevPnP.Core.AuthenticationManager
      $Ctx = $authManager.GetWebLoginClientContext($SiteURL)

      Also added the relevant packages from Nuget. Was very happy when the script ran, but clearly I am not as smart as I thought. ?‍♂️? the script only outputs the SCAs and the root web permissions – doesn’t recurse through subsites/lists/items etc.

      Reply
    • February 13, 2020 at 3:55 PM

      Hi Salaudeen,

      Is there a way to make this script work with MFA? We are not allowed to use app passwords either. TIA!

      Reply
    • February 14, 2020 at 7:29 AM

      Even After using switches in V2 of the script? -Recursive -ScanItemLevel -IncludeInheritedPermissions

      Reply
  • December 20, 2019 at 11:16 AM

    Thanks for writing this script. I am hitting an issue when the script hits an item with unique permissions that appears to be locked down ( even for the SPO Admin)
    Getting Permissions of List Items in the List: DataFeed
    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(
    s): “The remote server returned an error: (401) Unauthorized.”

    Now 1)I could add the list to the ExludedList but 2)I would prefer to generate a “Unable to read permissions on Item id : nn” and able to gracefully get passed this item.
    I have put a breakpoint on the line of code I think is the issue but any advice is welcome.

    Reply
    • December 23, 2019 at 1:36 PM

      You must have “Site collection Admin” rights! Add yourself to Site collection admin prior running the script!

      Reply
    • December 23, 2019 at 1:43 PM

      That is a good question. I believe I am as a member of admins group. it is only a certain listitem ID that seems to trigger the exception. I have Added this to your script to see what is causing the issue If ($ListItem.Id -eq nnnn)
      {
      Set-PSBreakpoint -Script Generate-SPOSitePermissionsRpt.Ps1 -Line 250
      }

      Reply
  • November 27, 2019 at 8:55 PM

    Hi Salaudeen, are we able to iterate through subsites and subsites of subsites?

    Reply
    • December 10, 2019 at 9:56 AM

      Hi Tony, Yes! This PowerShell script iterates through all subsites of all levels recursively.

      Reply
  • October 23, 2019 at 11:02 AM

    will the same script work for 2010?I need to compare source and target

    Reply
  • October 19, 2019 at 2:34 PM

    Awesome script, thanks a bunch! Saved me sooo much time.

    Reply
  • October 10, 2019 at 8:35 PM

    I’ve tried running this script (the v2 version) on an office 365 site, but it doesn’t seem to be working recursively. It lists the permissions of the objects on the site, but not for any folders or files in a document library. Any ideas on what I’m doing wrong?

    Reply
    • October 11, 2019 at 2:43 PM

      I’ve tried to do some debugging on this and when i put a break at “foreach ($Subweb in $Web.Webs)” and then look for at $web.webs.count it comes up as 0. The site I’m looking at has a few lists and a document library with some folders with unique permissions, but these are not being interrogated. Also the “If($recursive)” line is only being reached after the permissions of the immediate sites contents are noted. Is this normal?

      Reply
  • September 22, 2019 at 7:04 PM

    This is excellent stuff. I am concerned however about the execution time. I am analyzing a fairly large site collection and the script has been running for over 2 hours now. Is this typical?

    Also, can PowerShell handle 2 Progress Meters, where the first can show progress over the entire collection and the second as you currently have it?

    Reply
  • September 22, 2019 at 6:58 PM

    Version 1 Script is taking an exceptionally long time to run. Is this typical? I am analyzing a fairly large site collection. It has been running for over 2 hours now and not sure how close it is to completion. Can PowerShell handle two Progress Meters, The first to show progress over the entire collection and the second show progress as it currently does?

    Reply
  • September 16, 2019 at 5:12 PM

    Hi, thanks for the script. I got below, can you give me some suggestions please?
    ———————
    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The remote server returned an error: (500) Internal Server Error.”

    Reply
  • September 16, 2019 at 5:19 AM

    Hi, Is it possible to have it show the AzureAD displayName instead of the ObjectID on the Users?

    Reply
  • September 5, 2019 at 7:10 AM

    Thanks for a great script!
    Question – is it possible to run this on a specific folder/subfolder in the document library?

    Reply
  • August 1, 2019 at 9:48 PM

    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The remote server retur
    ned an error: (401) Unauthorized.”

    Reply
    • November 20, 2020 at 8:42 PM

      Add the account that you are using as a owner to the site.

      Reply
  • July 31, 2019 at 9:55 AM

    Hi,

    I have followed the script where we can find SharePoint Groups and their members along with the permissions, but it doesn’t give unique users list and their permissions and second , it gives GUIDs instead of names . Can you look into this ?

    Thanks

    Reply
    • July 31, 2019 at 3:50 PM

      And this doesn’t include AD groups too. We are looking for a script where we can find permissions of all groups ( AD and SharePoint both ) and users ( permissions given directly ) for a SharePoint Online site collection . How can this be achieved ?

      Reply
  • July 16, 2019 at 1:50 AM

    Hi, I’m having this error while running the script. Any clues of what might be wrong or where I could look for the problem? Thanks in advance!

    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “Entity (External Content Type) cannot be found with Namespace = ‘namespace’, Name = ‘Role’.”

    Reply
  • July 15, 2019 at 1:30 PM

    Thank you for this great script. I’m getting this error if you could help :

    Error Generating User Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The remote server returned an error: (500) Internal Server Error.”

    I ran a search and found many “ExecuteQuery()”. Do i need to put a value in everyone? and what value should they be?

    Thank you

    Reply
  • July 8, 2019 at 3:26 AM

    This has helped and working well as is. Thank you!

    Reply
  • July 8, 2019 at 5:59 AM

    thanks for the script! I am running it over one document library where sub-folders have different permissions. is there a way to change column A so that it includes the true path for example it’s currently showing
    https://hereismy.sharepoint.com/sites/hereismysitename/Documents/Forms/DispForm.aspx?ID=8280
    but I would like to show the folder structure instead of the ID:
    https://hereismy.sharepoint.com/sites/hereismysitename/Documents/name_of_folder/name_of_subfolder

    Also can you please confirm (I think I saw it in your screen shot) that if a user is added direct to the Document Library (not to a sharepoint permission group) that there name will appear on the output. Thank you 🙂

    Reply
  • June 27, 2019 at 10:55 AM

    Same error as just above for me too.

    Reply
    • June 27, 2019 at 12:12 PM

      i think it has something to do with the list view setting in SP Online, I’ve ran successfully on a doc library with 4000 files but it failed on one with 9000

      Reply
  • June 27, 2019 at 9:22 AM

    thanks works really well,
    i seem to get the below error on my larger document libraries, any idea why?
    “ExecuteQuery” with “0” argument(s): “The remote server returned an error: (429)

    thanks!

    Reply
  • February 14, 2019 at 1:58 PM

    Hey Salaudeen, it seems like this is the only script for that purpose, so thanks for writing it!

    I tried to run it and was able to successfully output some info like SC admins and permissions of the web, but when it gets to the function for the lists items, it fails with the following error:

    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “Cannot complete this action.

    Please try again.”

    Any ideas where to look?

    Reply
  • February 8, 2019 at 2:28 PM

    Thanks but I noticed that this isn’t iterating through the sharepoint groups and exporting out the members… can you add that?

    Reply
  • January 24, 2019 at 6:39 PM

    Seeing this error on running. Is there a problem with the function?

    PS C:usersVictorDesktop> .SPO-SiteCollectionPermissionsReport.ps1

    At C:usersVictorDesktopSPO-SiteCollectionPermissionsReport.ps1:127 char:48
    + … ewXml = “2000”
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Unexpected token ‘RecursiveAll”>2000″‘ in expression or statement.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : UnexpectedToken

    Reply
    • February 21, 2019 at 4:56 PM

      Thanks for the update. Any idea how to update this further? We have some pretty beefy lists/document library upwards of 5000 items. It seems to stall on bigger ones still.

      Reply
  • December 27, 2018 at 9:41 PM

    Salaudeen, this is great! But I’m still getting issues with lists over 5000 items — actually, lists over 2000 items. The script seems to stall. Are you sure the list threshold issue is resolved? Do you need to paginate the query?

    Reply
  • November 21, 2018 at 4:53 PM

    CAn i use this to get permissions for a specifi library?

    Reply
  • November 17, 2018 at 2:48 AM

    Thank you! This is a great script.

    The output for folders and subfolders are written as ../Forms/DispForm.aspx?ID=nnn. Can you include the actual name of the folders and subfolders?

    Thank you!

    Reply
  • November 15, 2018 at 12:32 AM

    Hi Salaudeen,

    Did you modify this script?

    I’m getting error like,

    “Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The sign-in name or password does not match one in the Microsoft account system.”

    I have entered the correct credentials and I’m a tenant admin for SharePoint online.

    Thanks.

    Reply
    • October 30, 2019 at 10:01 PM

      I am having the same error and I am using MFA. Where do you “Leave the -Credentials parameter” at?

      Reply
    • October 31, 2019 at 8:33 PM

      You will need to use your app password for MFA instead of the regular password you use. When you enable the MFA it displays a special app password string you will use for static apps or scripts to use.

      Reply
  • November 5, 2018 at 11:02 PM

    Hi I am getting below list view threshold error, any ideas please because we have more list in our sites.
    Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator.”

    Reply
    • November 11, 2018 at 1:09 PM

      This is because: You have larger lists with > 5000 List items. The script has been updated to handle larger lists. Try now!

      Reply
  • November 3, 2018 at 2:34 PM

    The script does not show a title for the list item

    Reply
  • October 31, 2018 at 3:34 PM

    This comment has been removed by the author.

    Reply
  • October 2, 2018 at 10:34 AM

    hi i have the same error
    Getting below error: Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The specified user could not be found.”

    #Read more: https://www.sharepointdiary.com/2018/09/sharepoint-online-site-collection-permission-report-using-powershell.html#ixzz5SlTVyKNr

    Reply
  • September 30, 2018 at 9:41 AM

    Getting below error: Error Generating Site Permission Report! Exception calling “ExecuteQuery” with “0” argument(s): “The specified user could not be found.”

    Any thought?

    Reply
    • October 3, 2018 at 1:38 PM

      Guess it happens when the user doesn’t exist (Orphan Users!).. Let me check if this can be avoided.

      Reply
  • September 19, 2018 at 9:20 AM

    I tried your script and it worked like a charm!! Thanks a Million Salaudeen!

    Reply

Leave a Reply