Need help to customize the PNP script for Sharepoint Access Report

Amarnath Jena 1 Reputation point
2023-01-10T23:56:11.433+00:00

I Need help to customize the PNP script for Sharepoint Access Report on each user specific access. Like user1 have 3 sites access with view permission . Next user2 on another row with same . I have attach the screenshot shows 278131-capture.png278123-pnpscriptforsharepointaccess.txtthat how i want the report to be generated and the script I am using which was provided by Microsoft Support team. Please help me on this at the earliest. Thank you.

Microsoft 365 and Office | SharePoint Server | For business
Microsoft 365 and Office | SharePoint | For business | Windows
Windows for business | Windows Server | User experience | PowerShell
{count} votes

8 answers

Sort by: Most helpful
  1. Amarnath Jena 1 Reputation point
    2023-01-11T15:04:41.83+00:00

    Can you generate the report like this ? I have shared the screenshot.Capture.PNG

    0 comments No comments

  2. Amarnath Jena 1 Reputation point
    2023-01-11T22:42:14.1933333+00:00

    Just to add and make the script easier for you. We just need the document libary at folder level access report for each user. The format will be the same for as the screenshot shared.

    0 comments No comments

  3. Yanli Jiang - MSFT 31,606 Reputation points Microsoft External Staff
    2023-01-12T08:05:19.5+00:00

    Hi @Amarnath Jena ,

    I have done some research and testing. According to your latest requirement, it is not recommended that you export all users’ permissions for each site at once, because it will take a lot of time to run.

    The following is for a user, export his permissions to all sites under the tenant, for your reference:

    #**********************************************************************************
    #* Instructions:                                                                  *
    #*                                                                                *
    #* Be sure you have installed the SharePoint Online Client Components SDK         *
    #* http://www.microsoft.com/en-in/download/details.aspx?id=42038                  *
    #*                                                                                *
    #* Ensure you run PowerShell ISE as Administrator                                 *
    #*                                                                                *
    #* NOTES:                                                                         * 
    #* - This will prompt you to log in twice                                         *
    #* - Any sites you do not have access to in SP will give you a 401 error          *
    #* - This does not include Groups/Teams only sites                                *
    #* - It takes a long time to run, depending on how many site collections you have *
    #**********************************************************************************
    
    
    #Set parameter values
    #**************************************
    #* User you are searching for         *
    #**************************************
    $UserAccount="i:0#.f|membership|******@domain.onmicrosoft.com"
    
    #**************************************
    #* File you want to output to         *
    #**************************************
    $ReportFile="C:\Users\spadmin\Desktop\AllSitesPermissionReport.csv"
    
    #**************************************
    #* Admin site for your SPO            *
    #**************************************
    $AdminSite = "https://domain-admin.sharepoint.com"
    
    #Load SharePoint CSOM Assemblies
    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"
    
    Install-Module Microsoft.Online.SharePoint.PowerShell #-Scope CurrentUser
    Install-Module SharePointPnPPowerShellOnline #-AllowClobber
      
    
    #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))
    }
    
    #Get Permissions Applied on a particular Object, such as: Web, List, Folder 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/Folder"
    
                #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()
    
                    #Check direct permissions
                    if($RoleAssignment.Member.PrincipalType -eq "User")
                    {
                        #Is the current user is the user we search for?
                        if($RoleAssignment.Member.LoginName -eq $SearchUser.LoginName)
                        {
                            Write-Host  -f Cyan "Found the User under direct permissions of the $($ObjectType) at $($ObjectURL)"
                             
                            #Get the Permissions assigned to user
                            $UserPermissions=@()
                            $Ctx.Load($RoleAssignment.RoleDefinitionBindings)
                            $Ctx.ExecuteQuery()
                            foreach ($RoleDefinition in $RoleAssignment.RoleDefinitionBindings)
                            {
                                $UserPermissions += $RoleDefinition.Name +";"
                            }
                            #Send the Data to Report file
                            "$($ObjectURL) `t $($ObjectType) `t $($Object.Title)`t Direct Permission `t $($UserPermissions)" | Out-File $ReportFile -Append
                        }
                    }
                     
                    Elseif($RoleAssignment.Member.PrincipalType -eq "SharePointGroup")
                    {
                            #Search inside SharePoint Groups and check if the user is member of that group
                            $Group= $Web.SiteGroups.GetByName($RoleAssignment.Member.LoginName)
                            $GroupUsers=$Group.Users
                            $Ctx.Load($GroupUsers)
                            $Ctx.ExecuteQuery()
    
                            #Check if user is member of the group
                            Foreach($User in $GroupUsers)
                            {
                                #Check if the search users is member of the group
                                if($user.LoginName -eq $SearchUser.LoginName)
                                {
                                    Write-Host -f Cyan "Found the User under Member of the Group '"$RoleAssignment.Member.LoginName"' on $($ObjectType) at $($ObjectURL)"
    
                                    #Get the Group's Permissions on site
                                    $GroupPermissions=@()
                                    $Ctx.Load($RoleAssignment.RoleDefinitionBindings)
                                    $Ctx.ExecuteQuery()
                                    Foreach ($RoleDefinition  in $RoleAssignment.RoleDefinitionBindings)
                                    {
                                        $GroupPermissions += $RoleDefinition.Name +";"
                                    }         
                                    #Send the Data to Report file
                                    "$($ObjectURL) `t $($ObjectType) `t $($Object.Title)`t Member of '$($RoleAssignment.Member.LoginName)' Group `t $($GroupPermissions)" | Out-File $ReportFile -Append
                                }
                            }
                    }
                }
    }
    
    #***********************
    #* Routine starts here *
    #***********************
    connect-SPOService -Url $AdminSite
    $sites = Get-SPOSite -Limit ALL
    
    write-host "Searching for User '" $UserAccount "'..."
    $Cred= Get-Credential
             
    #Write CSV- TAB Separated File) Header
    "URL `t Object `t Title `t PermissionType `t Permissions" | out-file $ReportFile
    foreach ($site in $sites) {
    
    Try {
    write-host -f Green "Checking Site '"$site.Url"'..."
    #Get Credentials to connect
             
            $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
    
    #Setup the context
            $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Site.Url)
            $Ctx.Credentials = $Credentials
    
            #Get the Web
            $Web = $Ctx.Web
            $Ctx.Load($Web)
            $Ctx.ExecuteQuery()
    
            #Get the User object
            $SearchUser = $Web.EnsureUser($UserAccount)
            $Ctx.Load($SearchUser)
            $Ctx.ExecuteQuery()
    
            #Write-host -f Yellow "Searching in the Site Collection Administrators Group..."
            #Check if Site Collection Admin
            If($SearchUser.IsSiteAdmin -eq $True)
            {
                Write-host -f Cyan "Found the User under Site Collection Administrators Group!"
                #Send the Data to report file
                "$($Web.URL) `t Site Collection `t $($Web.Title)`t Site Collection Administrator `t Site Collection Administrator" | Out-File $ReportFile -Append
              }
    
            #Function to Check Permissions of All List Items of a given List
            Function Check-SPOListItemsPermission([Microsoft.SharePoint.Client.List]$List)
            {
                Write-host -f Yellow "Searching in List Items of the List '"$List.Title "'..."
                $ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
                $Ctx.Load($ListItems)
                $Ctx.ExecuteQuery()
    
                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
                    }
                }
            }
    
            #Function to Check Permissions of all lists from the web
            Function Check-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
                        Check-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 Check Webs's Permissions from given URL
            Function Check-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 "Searching in the 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 "Searching in the Lists and Libraries of "$Web.URL"..."
                Check-SPOListPermission($Web)
      
                #Iterate through each subsite in the current web
                Foreach ($Subweb in $web.Webs)
                {
                        #Call the function recursively                           
                        Check-SPOWebPermission($SubWeb)
                }
            }
    
            #Call the function with RootWeb to get site collection permissions
            Check-SPOWebPermission $Web
    
             
    }
    
    Catch {
    "$($site.URL) `t `t `t Error Generating User Permission Report! $($_.Exception.Message) `t Site Collection Administrator" | Out-File $ReportFile -Append
            write-host -f Red "Error Generating User Permission Report!" $_.Exception.Message
        }
    Write-host -f Green "User Permission Report Generated Successfully!"
    }
    
    

    You can change the code according to your needs.

    01121

    01122


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

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


  4. Limitless Technology 44,766 Reputation points
    2023-01-12T16:59:50.84+00:00

    Hi,

    Thank you for posting your query.

    Kindly follow the steps provided below to resolve your issue.

    As a Global Administrator or SharePoint Administrator in Microsoft 365, you can allow custom script as a way of letting users change the look, feel, and behavior of sites and pages to meet organizational objectives or individual needs. If you allow custom script, all users who have "Add and Customize Pages" permission to a site or page can add any script they want. (By default, users who create sites are site owners and therefore have this permission.

    Go to this link for your reference and other troubleshooting procedures https://learn.microsoft.com/en-us/sharepoint/allow-or-prevent-custom-script

    Do not hesitate to message us if you need further assistance.

    If the answer is helpful kindly click "Accept as Answer" and up vote it.


  5. Amarnath Jena 1 Reputation point
    2023-01-12T18:33:32.7633333+00:00

    Hey Yanli,

    I need to generate a report for a site with folder level access . This script shows at a site level. I have a site where the site document libary have many folder's and sub folder's. I need to generate a report at folder level for a site. I am fine if sciprt take to much of time . Please make it for all user at once.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.