Tuesday, March 5, 2013

SharePoint Users and Groups Security Report Based on Permission Levels

Getting insights on who has access to  SharePoint sites & lists and what level of permission has been granted on all over site collection is a frequent requirement in SharePoint governance. Because, out of the box security reporting is very limited, I wrote this PowerShell script to generate SharePoint users and groups security report based on permission levels.

This report helps great in auditing user access on various SharePoint sites, lists to resolve any potential security risks according to the compliance. With the report, we can quickly and accurately get insights, such as

  • Report provides information about the list of users and groups who have been assigned permissions in the SharePoint site.
  •  It displays the list of assigned users and groups, account type (SharePoint user, AD group or SharePoint group), owner and members of the group and permission levels. 
  •  Analyses permissions for users and groups on any site or list.  So, its easy to analyze what a user has access to what.
  • It also lists out Site Permission Levels with their permissions defined for each one of them.
  • Additionally, this report gives list Permissions information where lists are with unique permissions. 

PowerShell Script to generate SharePoint users and groups security report based on permission levels

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
 
 #Region MOSS-2007-Cmdlets 

 Function global:Get-SPSite($url)
 {
  if($url -ne $null)
     {
     return New-Object Microsoft.SharePoint.SPSite($url)
  }
 }
 
 Function global:Get-SPWeb($url)
 {
   $site= Get-SPSite($url)
         if($site -ne $null)
             {
                $web=$site.OpenWeb();
       
             }
     return $web
 }
 
#EndRegion

Function GeneratePermissionReport()
{
 #Site Collection URL - Mandatory parameter
 param([Parameter(Mandatory=$true)] [string]$SiteCollectionURL)

  #Get the site collection
  $Site= Get-SPSite $SiteCollectionURL

  $web=$site.RootWeb
  
  #Get HTML File with CSS into the Output report
  $Content=Get-Content -Path "table.htm"  > PermissionReport.htm
  
   "<h2> $($Site.RootWeb.Title) - Permission Report</h2>" | out-file "PermissionReport.htm" -Append
  
  #Table of Contents
  "<h3> List of Sites under $($Site.RootWeb.Title)</h3> <table class='altrowstable' id='alternatecolor' cellpadding='5px'><tr><th>Site Name </th><th> URL </th></tr>" >> PermissionReport.htm
    #Get Users of All Webs : Loop throuh all Sub Sites
       foreach($Web in $Site.AllWebs) 
       {
    "<tr> <td> <a href='#$($web.Title.ToLower())'>$($web.Title)</a> </td><td> $($web.URL)</td> </tr>" >> PermissionReport.htm
    }
         
    #Get Users of All Webs : Loop throuh all Sub Sites
       foreach($Web in $Site.AllWebs) 
       { 
      #Check if site is using Unique Permissions or Inheriting from its Parent Site!
      if($Web.HasUniqueRoleAssignments -eq $true)
   {
    "</table><br/><hr> <h3>Site: [ <a name='$($Web.Title.ToLower())'>$($Web.Title) </a> ] at <a href='$($web.URL)'>$($web.URL)</a> is using Unique Permissions. </h3>" >> PermissionReport.htm 
   }
   else
   {
       "</table><br/><hr> <h3>Site: [ <a name='$($Web.Title.ToLower())'>$($Web.Title) </a> ] at <a href='$($web.URL)'>$($web.URL)</a> is Inheriting Permissions from its Parent Site.</h3>" >> PermissionReport.htm 
   }
   
   if($Web.HasUniqueRoleAssignments -eq $true)
   {    
    "<b>Site Users and Groups</b><table class='altrowstable' id='alternatecolor' cellpadding='5px'>" >> PermissionReport.htm 
    
       #Get the Role Assignments - (Users & Groups Granted access to the site) with each Role
     foreach($RoleDefinition in $Site.RootWeb.RoleDefinitions)
    { 
        #Write-Host $RoleDefinition.Name
     #Write Table Caption
     "<tr><th colspan='3'> <b>Permission Level: $($RoleDefinition.Name) <b> </th></tr>" >> PermissionReport.htm
     
     #Write Table Header
     "<tr> <td><b>Users/Groups </b></td> <td><b> Type </b></td> <td><b>User Name</b></td></tr>"  >> PermissionReport.htm

        foreach ($WebRoleAssignment in $web.RoleAssignments)
            {
       foreach($RoleDefinitionBinding in $WebRoleAssignment.RoleDefinitionBindings)
       {
       #If the current Role assignment contains the Site's Role Definition?
       if($RoleDefinitionBinding.Name -contains $RoleDefinition.Name)
       {
        #**** Get User/Group Type *****#
        #Is it a SharePoint Group?
        if($WebRoleAssignment.Member.LoginName -eq $NULL) 
        {
         $Type="SharePoint Group"
         $UserName=$WebRoleAssignment.Member.Name
         #Set Flag value for "Group Exists"
         $GroupExistsFlag=$true
        }
                        #Is it a SharePoint User Account or Domain Group?
        else
        {
            $UserName=$WebRoleAssignment.Member.LoginName
         #Is it a Domain Group?
         if($WebRoleAssignment.Member.IsDomainGroup)
         {
           $Type="Domain Group"
         }
         else 
         {
           $Type="SharePoint User"
         }
        }
        #Send Data to Report
        "<tr> <td> $($WebroleAssignment.Member.Name) </td><td> $($Type) </td><td> $($UserName) </td> </tr>"  >> PermissionReport.htm
       }
      }
     }
    }
      "</table></br> " >> PermissionReport.htm
     if($GroupExistsFlag -eq $true)
      {
       #**** Get All Members Group and its users ****
       "<b>Group Members</b><table class='altrowstable' id='alternatecolor' cellpadding='5px'><tr>" >> PermissionReport.htm
       foreach ($WebRoleAssignment in $web.RoleAssignments)
              {
         #Check if its a group
          if($WebRoleAssignment.Member.GetType().FullName -eq "Microsoft.SharePoint.SPGroup")
          {
           "<th colspan='2'><b>Group Name: $($WebRoleAssignment.Member.Name)<b></th></tr><tr><td><b>User ID</b></td><td><b>User Name</b></td></tr>" >> PermissionReport.htm
           foreach($User in $WebRoleAssignment.Member.users)
                                {
            "<tr><td> $($User.LoginName) </td><td> $($User.Name) </td></tr>" >> PermissionReport.htm
           }
          }
        }
         "</table> " >> PermissionReport.htm
      }
      #Reset Group Exists Flag 
      $GroupExistsFlag=$false
     }
     #*** Get All List & Library permissions with Unique Access ***#
       foreach($List in $Web.lists)
                {
        #Skip the Hidden Lists
                    if( ($List.HasUniqueRoleAssignments -eq $True) -and  ($List.Hidden -eq $false))
                    {
         "</table><br/><b>Users and Groups in List: [ $($List.Title) ] at <a href='$($List.ParentWeb.Url)/$($List.RootFolder.Url)'>$($List.ParentWeb.Url)/$($List.RootFolder.Url)</a> with Unique Permissions.</b><table class='altrowstable' id='alternatecolor' cellpadding='5px'><tr>" | Out-File PermissionReport.htm -Append
         "<td><b>Users/Groups </b></td><td> <b> Type </b></td><td><b> User Name </b></td></tr>"  >> PermissionReport.htm 
                      foreach($RoleDefinition in $site.RootWeb.RoleDefinitions)
         { 
          "<tr><th colspan='3'> Permission Level: $($RoleDefinition.Name)  </th></tr>" >> PermissionReport.htm
             #Get all the users granted permissions to the list
                   foreach($ListRoleAssignment in $List.RoleAssignments ) 
                      { 
           foreach($RoleDefinitionBinding in $ListRoleAssignment.RoleDefinitionBindings)
            {
             if($RoleDefinitionBinding.Name  -contains $RoleDefinition.Name)
              {
                #*** Get  User/Group Name *****#
                  $UserGroupName=$ListRoleAssignment.Member.Name
                 
                #**** Get User/Group Type *****#
               #Is it a SharePoint Group?
                if($ListRoleAssignment.Member.LoginName -eq $NULL) 
                {
                 $Type="SharePoint Group"
                 $UserName=$ListRoleAssignment.Member.Name
                }
                                #Is it a SharePoint User Account or Domain Group?
                else
                {
                    $UserName=$ListRoleAssignment.Member.LoginName
                 #Is it a Domain Group?
                 if($ListRoleAssignment.Member.IsDomainGroup)
                 {
                   $Type="Domain Group"
                 }
                 else #if($ListRoleAssignment.Member.LoginName)    
                 {
                   $Type="SharePoint User"
                 }
                }
               
                #Send the Data to Log file
                "<tr><td>$($UserGroupName) </td><td> $($Type) </td><td> $($UserName) </td></tr>" >> PermissionReport.htm
                }
               }
            }
                  }
                   }
       }
     #Dispose web object
     $web.dispose()  
     } 
     
     #*** Get Site Collection Permission Levels & Their base Permissions ***#
       "</table> <h2> Site Collection's Permission Levels & Their Base permissions </h2><p>"   >>PermissionReport.htm
       $site.RootWeb.RoleDefinitions | Where-Object {$_.hidden -eq $false} | ForEach-Object {
        "<b>Permission Level Name:</b> $($_.Name) <br/> <b> Permissions: </b>$($_.BasePermissions) <br/></p>" >>PermissionReport.htm
       }
       "</body></html>" >>PermissionReport.htm
    
    #Dispose the objects
    $Site.dispose()
    }
    
#Call the function to Generate Report
GeneratePermissionReport "http://sharepoint.crescent.com"

Report Output:
SharePoint Users and Groups Security Report Based on Permission Levels

This script uses a HTML File to apply CSS style to the report. You can refer my existing post:  SharePoint Users and Groups Permission Report to get the HTML file (table.htm).

BTW, Crescent is my arbitrary domain!



You might also like:
SharePoint Usage Reports
Usage reports, collaboration and audit for SharePoint.
Five Challenges in SharePoint Security
...And How to Solve Them. Free White Paper
*Sponsored


Check out these SharePoint products:

2 comments :

  1. The script you wrote is awesome! I've been looking for something like this for ever.

    ReplyDelete
  2. Awesome script. You should post it to Spiceworks along with a write up.

    If you don't want to I can post for you and ensure linked back to your site.

    ReplyDelete

Please Login and comment to get your questions answered!

You might also like:

Related Posts Plugin for WordPress, Blogger...