Skip to main content

PowerShell - CSOM code to get SharePoint Online Sites Permission 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"
     
  
$AdminSiteURL="https://m365x067565-admin.sharepoint.com/"
 
#Connect to SharePoint Online Admin
Write-host "Connecting to Admin Center..." -f Yellow
Connect-SPOService -url $AdminSiteURL -Credential (Get-Credential)
#Get each site collection and users
$Sites = Get-SPOSite -Limit ALL

Foreach($Site in $Sites)
{

$SiteURL=$Site.Url
 
}

#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=$Site.Url # "https://m365x067565.sharepoint.com/sites/ARTest/"
$ReportFile="C:\SitePermissionRpt.csv"
$BatchSize = 500
  
#Call the function
Generate-SPOSitePermissionRpt -SiteURL $SiteURL -ReportFile $ReportFile

Thanks  and I hope this will be helpful for you.

Comments

Popular posts from this blog

Update user language and regional settings with CSOM

Following my previous post around multilingual aspects of SharePoint Online:  Modify Site Regional and Language settings with JSOM and JavaScript Here is some CSOM code which updates the personal regional settings of the current user or another user (if you are a tenant admin and have the rights to update user profiles) Before update: The code: using Microsoft.SharePoint.Client ; using Microsoft.SharePoint.Client.UserProfiles ; using System.Security ; namespace UpdateLanguagePreference { class Program { static void Main ( string[] args ) { //Tenant Admin Details string tenantAdministrationUrl = " https://yoursite-admin.sharepoint.com/ " ; string tenantAdminLoginName = " tenantadmin@yoursite.onmicrosoft.com " ; string tenantAdminPassword = " password " ; //AccountName of the user whos property you want to update. ...

Power shell Script to get External Users on Office 365

Hello Everyone,  Below is the Powershell script to get all external users from office 365 tenant. #--------------------------------------------------------------------------------------------------------------------------- $host.Runspace.ThreadOptions = "ReuseThread" #Definition of the function that gets all the external users in a SharePoint Online Tenant. function Get-SPOExternalUsers {     param ($sUserName,$sMessage,$sSPOAdminCenterUrl)     try     {             Write-Host "----------------------------------------------------------------------------"  -foregroundcolor Green         Write-Host "Getting all the external users in a SharePoint Online Tenant" -foregroundcolor Green         Write-Host "----------------------------------------------------------------------------"  -foregroundcolor Green         $msolcred = Get-Credential -UserName...

Build and Deploy a custom theme in SharePoint 2019: Using C# and Site features

Custom Theme and Branding are common to use cases and all kinds of business users like to have the personalized team and collaboration sites. today I am posting C# code that will help to build custom features for SharePoint 2019 site.   If need any assistance, I would be happy to help: kamal_pandey@outlook.com  ----------------------------- Code to build  custom features---------- using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.SharePoint; using Microsoft.SharePoint.Utilities; namespace SharePointBranding.Code {     public class BrandingManager     {         public SPWeb Web { get; set; }         public BrandingManager(SPWeb web)         {             Web = web;         }         public void SetMasterPage(stri...