Tuesday, January 8, 2013

SharePoint 2010 Permission Report: Check Access Rights for a Specific User

Update: This script has been updated to scan Folders and List Items with Claims support at: SharePoint User Permission Analysis & Reporting using PowerShell
Requirement: To ensure security, generate permissions report on all locations like (sites, lists, etc.) where a specific user has permissions.

When people moving from one role to another, Its necessary to audit their permissions on sites and lists where user has access rights. But unfortunately, There is no out of the box ways to find all sites and lists where a particular user has been granted access in SharePoint with out using third party tools. Luckily, We've PowerShell! Lets find all SharePoint sites and lists where a particular user has access rights.

PowerShell Script to Check and Generate Report on Access Rights for a Specific User:
With this script, you can analyze and track the security effectively check what permissions on an account has been granted on each all places in SharePoint. This PowerShell script scans these areas to to retrieve a specific user's access rights:
  • Farm Administrator's Group
  • Central Administration Web Application Policies
  • Site Collection Administrators 
  • Scans the all Site collections and Sub-sites with Unique Permissions
  • Scans all Lists and Libraries with unique permissions
  • Scans all Groups which has permissions on sites and Lists
After executing the script, it generates a CSV file (Tab Separated, In fact!) with details: URL, Site/List, Title, Permission Type, Permissions as in the below screenshot.
SharePoint Permission Report: Check Access Rights for a Specific User

We want to track How many Sites user has permissions, How many Lists or Libraries user has explicitly added and so on based on business needs.

PowerShell Script to Retrieve User Access Rights Across web application:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
 
Function GetUserAccessReport($WebAppURL, $SearchUser)
{

    #Output Report location
    $OutputReport = "C:\Scripts\UserAccessReport.csv"
    #delete the file, If already exist!
    if (Test-Path $OutputReport)
     {
        Remove-Item $OutputReport
     }

Write-host "Scanning Farm Administrator Group..." 

#Write CSV- TAB Separated File) Header
"URL `t Site/List `t Title `t PermissionType `t Permissions" | out-file $OutputReport
 
  ####Check Whether the Search Users is a Farm Administrator ###
  #Get the SharePoint Central Administration site
  $AdminWebApp= Get-SPwebapplication -includecentraladministration | where {$_.IsAdministrationWebApplication}
    $AdminSite = Get-SPweb($AdminWebApp.Url)
    $AdminGroupName = $AdminSite.AssociatedOwnerGroup
    $FarmAdminGroup = $AdminSite.SiteGroups[$AdminGroupName]
 
 #enumerate in farm adminidtrators groups
    foreach ($user in $FarmAdminGroup.users)
    {
     if($user.LoginName -eq $SearchUser)
     {
       "$($AdminWebApp.URL) `t Farm `t $($AdminSite.Title)`t Farm Administrator `t Farm Administrator" | Out-File $OutputReport -Append
     }     
    }
 
Write-host "Scanning Web Application Policies..." 

 ### Check Web Application Policies ###
  $WebApp= Get-SPWebApplication $WebAppURL
 
  foreach ($Policy in $WebApp.Policies)
  {
      #Check if the search users is member of the group
     if($Policy.UserName -eq $SearchUser)
       {
       #Write-Host $Policy.UserName
        $PolicyRoles=@()
       foreach($Role in $Policy.PolicyRoleBindings)
       {
        $PolicyRoles+= $Role.Name +";"
       }
       #Write-Host "Permissions: " $PolicyRoles
      "$($AdminWebApp.URL) `t Web Application `t $($AdminSite.Title)`t  Web Application Policy `t $($PolicyRoles)" | Out-File $OutputReport -Append
   }
  }

 Write-host "Scanning Site Collections..." 
 #Get All Site Collections of the WebApp
 $SiteCollections = Get-SPSite -WebApplication $WebAppURL -Limit All
    
  #Loop through all site collections
   foreach($Site in $SiteCollections)
    {
     Write-host "Scanning Site Collection:" $site.Url
     #Check Whether the Search User is a Site Collection Administrator
     foreach($SiteCollAdmin in $Site.RootWeb.SiteAdministrators)
        {
      if($SiteCollAdmin.LoginName -eq $SearchUser)
      {
       "$($Site.RootWeb.Url) `t Site `t $($Site.RootWeb.Title)`t Site Collection Administrator `t Site Collection Administrator" | Out-File $OutputReport -Append
      }     
    }
   
     #Loop throuh all Sub Sites
  foreach($Web in $Site.AllWebs)
  {
      if($Web.HasUniqueRoleAssignments -eq $True)
            {
             Write-host "Scanning Site:" $Web.Url
    
            #Get all the users granted permissions to the list
              foreach($WebRoleAssignment in $Web.RoleAssignments )
    {
                 #Is it a User Account?
          if($WebRoleAssignment.Member.userlogin)   
           {
              #Is the current user is the user we search for?
              if($WebRoleAssignment.Member.LoginName -eq $SearchUser)
             {
               #Write-Host  $SearchUser has direct permissions to site $Web.Url
               #Get the Permissions assigned to user
       $WebUserPermissions=@()
                foreach ($RoleDefinition  in $WebRoleAssignment.RoleDefinitionBindings)
                {
                 $WebUserPermissions += $RoleDefinition.Name +";"
                }
               #write-host "with these permissions: " $WebUserPermissions
          
         #Send the Data to Log file
               "$($Web.Url) `t Site `t $($Web.Title)`t Direct Permission `t $($WebUserPermissions)" | Out-File $OutputReport -Append
             }
           }
        #Its a SharePoint Group, So search inside the group and check if the user is member of that group
         else 
          {
                        foreach($user in $WebRoleAssignment.member.users)
                            {
                #Check if the search users is member of the group
               if($user.LoginName -eq $SearchUser)
                {
                  #Write-Host  "$SearchUser is Member of " $WebRoleAssignment.Member.Name "Group"
                  #Get the Group's Permissions on site
                $WebGroupPermissions=@()
                  foreach ($RoleDefinition  in $WebRoleAssignment.RoleDefinitionBindings)
                  {
                      $WebGroupPermissions += $RoleDefinition.Name +";"
                     }
                #write-host "Group has these permissions: " $WebGroupPermissions
               
               #Send the Data to Log file
               "$($Web.Url) `t Site `t $($Web.Title)`t Member of $($WebRoleAssignment.Member.Name) Group `t $($WebGroupPermissions)" | Out-File $OutputReport -Append
              }
             }
     }
    }
      } 
     
    ###*****  Check Lists with Unique Permissions *******###
   foreach($List in $Web.lists)
   {
             if($List.HasUniqueRoleAssignments -eq $True -and ($List.Hidden -eq $false))
                {
                 Write-host "Scanning List:" $List.RootFolder.Url
                    #Get all the users granted permissions to the list
     foreach($ListRoleAssignment in $List.RoleAssignments )
                    {
                     #Is it a User Account?
             if($ListRoleAssignment.Member.userlogin)   
              {
                 #Is the current user is the user we search for?
                 if($ListRoleAssignment.Member.LoginName -eq $SearchUser)
                {
                  #Write-Host  $SearchUser has direct permissions to List ($List.ParentWeb.Url)/($List.RootFolder.Url)
                  #Get the Permissions assigned to user
                   $ListUserPermissions=@()
                    foreach ($RoleDefinition  in $ListRoleAssignment.RoleDefinitionBindings)
                    {
                                 $ListUserPermissions += $RoleDefinition.Name +";"
                                }
                  #write-host "with these permissions: " $ListUserPermissions
              
                  #Send the Data to Log file
                  "$($List.ParentWeb.Url)/$($List.RootFolder.Url) `t List `t $($List.Title)`t Direct Permissions `t $($ListUserPermissions)" | Out-File $OutputReport -Append
                }
              }
              #Its a SharePoint Group, So search inside the group and check if the user is member of that group
             else 
              {
       foreach($user in $ListRoleAssignment.member.users)
       {
                   if($user.LoginName -eq $SearchUser)
                    {
                     #Write-Host  "$SearchUser is Member of " $ListRoleAssignment.Member.Name "Group"
                      #Get the Group's Permissions on site
                    $ListGroupPermissions=@()
                      foreach ($RoleDefinition  in $ListRoleAssignment.RoleDefinitionBindings)
                      {
                                  $ListGroupPermissions += $RoleDefinition.Name +";"
                                 }
                    #write-host "Group has these permissions: " $ListGroupPermissions
               
                    #Send the Data to Log file
                    "$($Web.Url) `t Site `t $($List.Title)`t Member of $($ListRoleAssignment.Member.Name) Group `t $($ListGroupPermissions)" | Out-File $OutputReport -Append
                  }
                }
             }
                    }
                }
            }
     }
 }
     
 Write-host "`n Access Rights Report Generated!" 
 }
 

#Call the function to Check User Access
GetUserAccessReport "http://sharepoint.crescent.com" "i:0#.w|Global\Salaudeen"

You can Download the complete PowerShell Script from MSDN Code Gallery: SharePoint Permission Report: Check Access Rights for a Specific User

Limitation: Currently, it doesn't count on active directory groups! Say, for e.g. an active directory security group may include the user you are searching for and that group may be granted with access rights. Also, it doesn't go til folder, list Item level. it stops at List.

Huh, another nifty script under my SharePoint Admin tool belt!



You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Document SharePoint Farm
Automatically generate SharePoint documentation.
*Sponsored


Check out these SharePoint products:

18 comments :

  1. Hi Salaudeen - Thanks for sharing your work. This looks like a great tool, however I receive errors when running it. All I did was change " GetUserAccessReport "http://sharepoint.crescent.com" "Global\Salaudeen" " to the URL of my SharePoint URL and one of my users. The error is:

    GetUserAccessReport : Exception has been thrown by the target of an invocation.
    At D:\Scripts\scratch\UserAccessReport1.ps1:165 char:20
    + GetUserAccessReport <<<< "https://sharepoint.domain.edu" "domain\fwhite"
    + CategoryInfo : NotSpecified: (:) [GetUserAccessReport], TargetInvocationException
    + FullyQualifiedErrorId : System.Reflection.TargetInvocationException,GetUserAccessReport

    Do you have any suggestions on working though this? Thanks - Greg

    ReplyDelete
    Replies
    1. Greg,
      Sounds like its a permissions issue! You must have permission on the site collection(s) in question! Try creating new Web Application User Policy in Central Admin on the target web application.

      Delete
  2. Greg,
    Make sure you do not have any site collection is set to No Access.
    Joseph Pullakudy

    ReplyDelete
  3. I am getting the following error while running this.
    PS C:\Scripts> & '.\User Access Report.ps1'
    The following exception occurred while trying to enumerate the collection:
    "0x80070003".
    At C:\Scripts\User Access Report.ps1:58 char:24
    + foreach($Web in $Site.AllWebs)
    + ~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException
    + FullyQualifiedErrorId : ExceptionInGetEnumerator

    ReplyDelete
    Replies
    1. The account you are running this script must have access to the site! Also must have DBO permissions on the databases used by SharePoint. Another case: Site may be locked!

      Delete
  4. Hi, But where did this generate the file.
    i have run the script with no error and went to the log file but no luck dint find the file.
    Please let me know where to find the location.

    Thanks and Regards,

    Sabby

    ReplyDelete
    Replies
    1. Sabby, It should be generated as "UserAccessReport.csv" on the same location where you saved this PowerShell script.

      Delete
  5. Hello, this works great! but I'm trying to modify it a tiny bit.. to have it add a new user, where it found the $searchuser, and copy the role from the search user. I have the below added in, but I can't get it to copy the 'role name' correctly into the below, for $permlevel:

    $WebUserPermissions=@()
    foreach ($RoleDefinition in $WebRoleAssignment.RoleDefinitionBindings)
    {
    $WebUserPermissions += $RoleDefinition.Name +";"
    $permlevel = $RoleDefinition.Name
    $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($account)
    $role = $_.RoleDefinitions.($permlevel)
    $assignment.RoleDefinitionBindings.Add($role)
    $_.RoleAssignments.Add($assignment)

    ReplyDelete
  6. Hi,
    As this script is for a particular user. Can i get such report for all users in one report?

    ReplyDelete
  7. Is there a script that does this for Sharepoint 2010?

    ReplyDelete
    Replies
    1. Chris, its Verified in SharePoint 2010 and SharePoint 2013!

      Delete
  8. Hi I need script for single user which sites accessing that sites his level of acess and primary and secondary admin contact

    ReplyDelete
  9. Hi looks like a great job your script, I need something like that but for all the users in my site and obviously I dont know all the users id or names :(, what can I do ?

    Regards

    ReplyDelete
  10. Hi,
    Could you please help me with the script to get all users from all the web application to get the entire SharePoint permission report.

    Thanks

    ReplyDelete
  11. Getting errors :
    You cannot call a method on a null-valued expression. for line 11 char 27

    Export-Csv : A parameter cannot be found that matches parameter name 'Append'. line 179 char: 78

    These errors are from the start....

    ReplyDelete
  12. Hi Salaudeen,

    I get the below error. Can you please help me.

    Get-SPWebApplication : Cannot find an SPWebApplication object with Name, Id, or
    Url: <a class=.
    At C:\Admin\GetUserPermissionsTest.ps1:38 char:32
    + $WebApp= Get-SPWebApplication <<<< $WebAppURL
    + CategoryInfo : InvalidData: (Microsoft.Share...tWebApplication:
    SpCmdletGetWebApplication) [Get-SPWebApplication], SPCmdletPipeBindExcepti
    on
    + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SpCmdletGetWebAp
    plication

    Scanning Site Collections...
    Get-SPSite : Cannot find an SPWebApplication object with Name, Id, or Url: <a c
    lass=.
    At C:\Admin\GetUserPermissionsTest.ps1:58 char:31
    + $SiteCollections = Get-SPSite <<<< -WebApplication $WebAppURL -Limit All
    + CategoryInfo : InvalidData: (Microsoft.Share...SPCmdletGetSite:
    SPCmdletGetSite) [Get-SPSite], SPCmdletPipeBindException
    + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletGetSite

    ReplyDelete
    Replies
    1. Try Changing the Web Application URL and User ID in Line#187

      Delete

Please Login and comment to get your questions answered!

You might also like:

Related Posts Plugin for WordPress, Blogger...