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
Output Report of the script:
The above script generates a CSV file in the provided ReportFile parameter. Here is a sample report generated.
If you are looking for 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:
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 permission report on all objects which has unique permissions on the given site collection. It scans through 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.
#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 $Permissions=@() $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.
If you are looking for 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 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 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 -IncludeInheritedPermissionsThis script produces output as below! It gets SharePoint Online site and subsites along with its child object permission using PowerShell
SharePoint Online: Site Collection Permissions Report using PowerShell
Reviewed by Salaudeen Rajack
on
September 06, 2018
Rating:

I tried your script and it worked like a charm!! Thanks a Million Salaudeen!
ReplyDeleteGetting below error: Error Generating Site Permission Report! Exception calling "ExecuteQuery" with "0" argument(s): "The specified user could not be found."
ReplyDeleteAny thought?
Guess it happens when the user doesn't exist (Orphan Users!).. Let me check if this can be avoided.
Deletehi i have the same error
ReplyDeleteGetting below error: Error Generating Site Permission Report! Exception calling "ExecuteQuery" with "0" argument(s): "The specified user could not be found."
#Read more: http://www.sharepointdiary.com/2018/09/sharepoint-online-site-collection-permission-report-using-powershell.html#ixzz5SlTVyKNr
Script has been updated! Try now.
DeleteThis comment has been removed by the author.
ReplyDeleteThe script does not show a title for the list item
ReplyDeleteHi I am getting below list view threshold error, any ideas please because we have more list in our sites.
ReplyDeleteError 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."
This is because: You have larger lists with > 5000 List items. The script has been updated to handle larger lists. Try now!
DeleteHi Salaudeen,
ReplyDeleteDid 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.
I am having the same error and I am using MFA. Where do you "Leave the -Credentials parameter" at?
DeleteYou 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.
DeleteYes, When you have MFA enabled, You have to use App Passwords to authenticate through scripts! Here is how to create an App Password: How to Create App Password in Office 365?
DeleteThank you! This is a great script.
ReplyDeleteThe 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!
CAn i use this to get permissions for a specifi library?
ReplyDeleteSure.. Here you go: SharePoint Online: PowerShell to Get List Permissions
DeleteSalaudeen, 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?
ReplyDeleteSeeing this error on running. Is there a problem with the function?
ReplyDeletePS C:\users\Victor\Desktop> .\SPO-SiteCollectionPermissionsReport.ps1
At C:\users\Victor\Desktop\SPO-SiteCollectionPermissionsReport.ps1:127 char:48
+ ... ewXml = "2000"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unexpected token 'RecursiveAll">2000"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
Wrap "RecursiveAll" with 'RecursiveAll' (Replace "" with ')
DeleteThanks 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.
DeleteThanks but I noticed that this isn't iterating through the sharepoint groups and exporting out the members... can you add that?
ReplyDeleteHey Salaudeen, it seems like this is the only script for that purpose, so thanks for writing it!
ReplyDeleteI 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?
Could happen in slow connections. Try setting RowLimit from 500 to 100
Deletethanks works really well,
ReplyDeletei 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!
Same error as just above for me too.
ReplyDeletei 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
DeleteScript has been updated with batch processing and progress bars. Try now!
DeleteThis has helped and working well as is. Thank you!
ReplyDeletethanks 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
ReplyDeletehttps://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 :)
Thank you for this great script. I'm getting this error if you could help :
ReplyDeleteError 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
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!
ReplyDeleteError Generating Site Permission Report! Exception calling "ExecuteQuery" with "0" argument(s): "Entity (External Content Type) cannot be found with Namespace = 'namespace', Name = 'Role'."
Hi,
ReplyDeleteI 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
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 ?
DeleteError Generating Site Permission Report! Exception calling "ExecuteQuery" with "0" argument(s): "The remote server retur
ReplyDeletened an error: (401) Unauthorized."
Thanks for a great script!
ReplyDeleteQuestion - is it possible to run this on a specific folder/subfolder in the document library?
You can get permissions of a SharePoint Folder with my another script: SharePoint Online: Get Folder Permissions using PowerShell
DeleteHi, Is it possible to have it show the AzureAD displayName instead of the ObjectID on the Users?
ReplyDeleteHi, thanks for the script. I got below, can you give me some suggestions please?
ReplyDelete---------------------
Error Generating Site Permission Report! Exception calling "ExecuteQuery" with "0" argument(s): "The remote server returned an error: (500) Internal Server Error."
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?
ReplyDeleteThis 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?
ReplyDeleteAlso, can PowerShell handle 2 Progress Meters, where the first can show progress over the entire collection and the second as you currently have it?
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?
ReplyDeleteI'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?
DeleteAwesome script, thanks a bunch! Saved me sooo much time.
ReplyDeletewill the same script work for 2010?I need to compare source and target
ReplyDeleteThis is written for SharePoint Online! For SharePoint On-premises, use: SharePoint Site Permission Report using PowerShell
DeleteHi Salaudeen, are we able to iterate through subsites and subsites of subsites?
ReplyDelete