1

we are using O365/SharePoint Online 2013.

Is there any way to check a specific user's permissions for the root site in question and all of its subsites so basically all sites in a site collection? We have 10 subsites and some users can access a few of them and some might have the access to every one of them.

From time to time I get asked to check where one specific user has access to and at the moment the only way I have found is to check the user permissions one site at a time. That is quite time-consuming, so is there any easy/quick way to see all the sites a user has access to?

EDIT: I found this possible management shell method but I was hoping for a simpler/easier method that could be done via SPO user interface. And also this method doesn't seem to do exactly what I'm searching for.

I greatly appreciate any information regarding this matter!

2
  • check this oen social.technet.microsoft.com/Forums/en-US/… – Waqas Sarwar MVP Mar 27 '15 at 13:51
  • @WaqasSarwarMCSE thank you for your comment! Still it seems those instructions are about checking the permissions of a user on one (1) specific site, not the subsites (or just a whole site collection). It's beginning to look like there is no way to achieve what I want with O365/SPO. :/ – Tenttu Apr 7 '15 at 5:43
5

I manage over 400 groups and faced the same issue. I don't have Farm access and use SharePoint 2010 so I don't know if this would work for 365. Our group name format uses the subsite name and permission level. I use a script in a Content Editor Web Part on the main site to display all the groups and users. Then I can Ctrl-f through the list to find a particular user and determine which groups and subsites they can access by the group name. It also gives me a great snapshot of permission levels at that point in time.

Requires jQuery reference in line 19:

<!-- PLACE THIS CODE IN A 'CONTENT EDITOR' WEB PART  
     THIS SCRIPT PULLS ALL GROUPS IN THE SITE COLLECTION REGARDLESS OF PERMISSIONS LEVELS -->

<h2>Administrative Page - Whole Site Access Detail</h2>
<h3>Displays users that have access to any part of the site.</h3>
<input id="btnPrintTable" style="display:none;" onclick="printTable()" type="button" value="Print preview..."/> 
<input id="btnCopyTable" style="display:none;" onclick="copyTable()" type="button" value="Select table"/> 
<p></p>

<table class="groupUsers" id="groupUsersTable">
    <tbody>
        <tr>
            <td>Page loading...If this takes a while, the script may not be linked properly.</td>
        </tr>
    </tbody>
</table>

// MODIFY TO YOUR LOCATION
<script src="[location of your jquery script]/Supporting_Code/jquery-1.8.3.min.js" type="text/javascript">
// Load jquery from SharePoint directory
</script>

<script type="text/javascript">  
// Retrieves group IDs from page and pulls associated users.

// Clear the Table and notify user the script is processing.
$("#groupUsersTable").empty();
$("#groupUsersTable").append("<tr><td>Page loading...</td></tr>");

function retrieveAllUsersAllGroups() {
    $("#groupUsersTable").empty();
    $("#groupUsersTable").append("<tr><td>Retrieving users for the list...</td></tr>");
    var clientContext = SP.ClientContext.get_current();
    this.collGroup = clientContext.get_web().get_siteGroups();

    clientContext.load(collGroup);
    clientContext.load(collGroup, 'Include(Users)');
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onMyQuerySucceeded), Function.createDelegate(this, this.onMyQueryFailed)); }

function onMyQuerySucceeded() {
    // Clear the Table
    $("#groupUsersTable").empty();
    // Add Table Headers
    $("#groupUsersTable").append("<tr><th>Group</th><th>Users</th></tr>");

    var groupEnumerator = collGroup.getEnumerator();
    while (groupEnumerator.moveNext()) {
        var oGroup = groupEnumerator.get_current();
        var strGroup = oGroup.get_title();
        // Build row and add to Table
        var tableHTML = "<tr><td class='col1'>"+strGroup+"</td><td class='col2'></td></tr>";
        $("#groupUsersTable").append("<tr><td></td><td></td></tr>"); // Blank line between group sets
        $("#groupUsersTable").append(tableHTML);
        // Retrieve users for current group.
        var collUser = oGroup.get_users();
        var userEnumerator = collUser.getEnumerator();
        while (userEnumerator.moveNext()) {
            var oUser = userEnumerator.get_current();
            var rowHTML = "<tr><td class='col1'></td><td class='col2'>"+oUser.get_title()+"</td></tr>";
            $("#groupUsersTable").append(rowHTML);
        }
    }   
    // a table was populated so show the copy/print buttons.
    showMyButton();
}

function onMyQueryFailed(sender, args) {

    alert('User retrieval failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

function showMyButton() {
    // Remove page loading notice and show the button
    $('#btnPrintTable').show(500);
    $('#btnCopyTable').show(500);
}

// Call the script once sp.js has completely loaded.
ExecuteOrDelayUntilScriptLoaded(retrieveAllUsersAllGroups, "sp.js");

function printTable() {
    var printTableArea=document.getElementById('groupUsersTable');
    newWin= window.open("");
    newWin.document.write(printTableArea.outerHTML);
    newWin.print();
}

function copyTable() {
    var el = document.getElementById('groupUsersTable');
    var body = document.body, range, sel;
    if (document.createRange && window.getSelection) {
        range = document.createRange();
        sel = window.getSelection();
        sel.removeAllRanges();
        try {
            range.selectNodeContents(el);
            sel.addRange(range);
        } catch (e) {
            range.selectNode(el);
            sel.addRange(range);
        }
    } else if (body.createTextRange) {
        range = body.createTextRange();
        range.moveToElementText(el);
        range.select();
        range.execCommand("Copy");
    }
}

</script>
1
  • This seems like an elegant way to do what I asked. I'll test it as soon as I'm back in the office. Thank you! – Tenttu May 17 '16 at 6:24
0

Found a PowerShell script here which scans the following areas to to retrieve a specific user's access rights. 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.

  • 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.

enter image description here

You can download the script from here

In case the site goes down, here is the script:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue


#Function to retrieve Permission data - Coded by Salaudeen Rajack: http://www.SharePointDiary.com
Function Get-PermissionInfo([String]$UserID, [Microsoft.SharePoint.SPSecurableObject]$Object)
{
 #Object Array to hold Permission data
    $PermissionDataCollection = @()

 #Determine the given Object type and Get URL of it
    switch($Object.GetType().FullName)
 {
  "Microsoft.SharePoint.SPWeb"  { $ObjectType = "Site" ; $ObjectURL = $Object.URL }
  "Microsoft.SharePoint.SPListItem"
  {
   if($Object.Folder -ne $null)
   {
     $ObjectType = "Folder" ; $ObjectURL = "$($Object.Web.Url)/$($Object.Url)"
   }
   else
   {
    $ObjectType = "List Item"; $ObjectURL = "$($Object.Web.Url)/$($Object.Url)"
   }
  }
  #Microsoft.SharePoint.SPList, Microsoft.SharePoint.SPDocumentLibrary, "Microsoft.SharePoint.SPPictureLibrary",etc
  default { $ObjectType = "List/Library"; $ObjectURL = "$($Object.ParentWeb.Url)/$($Object.RootFolder.URL)" }
 }

 #Get Permissions of the user on given object - Such as: Web, List, Folder, ListItem
 $UserPermissionInfo = $Object.GetUserEffectivePermissionInfo($UserID)
 #Iterate through each permission and get the details
 foreach($UserRoleAssignment in $UserPermissionInfo.RoleAssignments)
 {
  #Get all permission levels assigned to User account directly or via SharePOint Group
  $UserPermissions=@()
        foreach ($UserRoleDefinition in $UserRoleAssignment.RoleDefinitionBindings)
        {
   #Exclude "Limited Accesses"
   if($UserRoleDefinition.Name -ne "Limited Access")
   {
          $UserPermissions += $UserRoleDefinition.Name
   }
        }

  #Determine Permissions granted directly or through SharePoint Group
  if($UserPermissions)
  {
   if($UserRoleAssignment.Member -is [Microsoft.SharePoint.SPGroup])  
   {
     $PermissionType = "Member of SharePoint Group: " + $UserRoleAssignment.Member.Name    
   }
   else
   {
    $PermissionType = "Direct Permission"
   }
   $UserPermissions = $UserPermissions -join ";" 

   #Create an object to hold storage data
         $PermissionData = New-Object PSObject
         $PermissionData | Add-Member -type NoteProperty -name "Object" -value $ObjectType
   $PermissionData | Add-Member -type NoteProperty -name "Title" -value $Object.Title
         $PermissionData | Add-Member -type NoteProperty -name "URL" -value $ObjectURL 
   $PermissionData | Add-Member -type NoteProperty -name "Permission Type" -value $PermissionType
   $PermissionData | Add-Member -type NoteProperty -name "Permissions" -value $UserPermissions
   $PermissionDataCollection += $PermissionData
  }  
 }
 Return $PermissionDataCollection
}

#Function to Generate Permission Report
Function Generate-PermissionReport($UserID, $WebAppURL, $ReportPath)
{
    #Output Report location, delete the file, If already exist!
    if (Test-Path $ReportPath)
     {
        Remove-Item $ReportPath
     }

   #Write Output Report CSV File Headers
  "Object, Title, URL, Permission Type, Permissions" | out-file $ReportPath

 ###Check Whether the Search Users is a Farm Administrator ###
 Write-host "Scanning Farm Administrators..."
   #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.Endswith($UserID,1)) #1 to Ignore Case
     {
       "Farm, $($AdminSite.Title), $($AdminWebApp.URL), Farm Administrators Group, Farm Administrator" | Out-File $ReportPath -Append
     }    
    }

 ### Check Web Application User Policies ###
 Write-host "Scanning 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.EndsWith($UserID,1))
       {
       #Write-Host $Policy.UserName
        $PolicyRoles=@()
       foreach($Role in $Policy.PolicyRoleBindings)
       {
        $PolicyRoles+= $Role.Name +";"
       }
   #Send Data to CSV File
      "Web Application, $($WebApp.Name), $($WebApp.URL), Web Application Policy, $($PolicyRoles)" | Out-File $ReportPath -Append
   }
  }

 #Convert UserID Into Claims format - If WebApp is claims based! Domain\User to i:0#.w|Domain\User
    if($WebApp.UseClaimsAuthentication)
    {
        $ClaimsUserID = (New-SPClaimsPrincipal -identity $UserID -identitytype 1).ToEncodedString()
    }

 #Get all Site collections of given web app
 $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 User is a Site Collection Administrator
     foreach($SiteCollAdmin in $Site.RootWeb.SiteAdministrators)
        {
      if($SiteCollAdmin.LoginName.EndsWith($ClaimsUserID,1))
      {
       "Site Collection, $($Site.RootWeb.Title), $($Site.RootWeb.Url), Site Collection Administrators Group, Site Collection Administrator" | Out-File $ReportPath -Append
      }    
    }

  #Get all webs
  $WebsCollection = $Site.AllWebs
  #Loop throuh each Site (web)
  foreach($Web in $WebsCollection)
  {
       if($Web.HasUniqueRoleAssignments -eq $True)
             {
     Write-host "Scanning Site:" $Web.Url

     #Get Permissions of the user on Web
     $WebPermissions = Get-PermissionInfo $ClaimsUserID $Web

     #Export Web permission data to CSV file - Append
     $WebPermissions |  Export-csv $ReportPath  -notypeinformation -Append
    }

    #Check Lists with Unique Permissions
    Write-host "Scanning Lists on $($web.url)..."
    foreach($List in $web.Lists)
    {
              if($List.HasUniqueRoleAssignments -eq $True -and ($List.Hidden -eq $false))
                 {
      #Get Permissions of the user on list
                        $ListPermissions = Get-PermissionInfo $ClaimsUserID $List

      #Export Web permission data to CSV file - Append
      $ListPermissions |  Export-csv $ReportPath -notypeinformation -Append      
     }

     #Check Folders with Unique Permissions
     $UniqueFolders = $List.Folders | where { $_.HasUniqueRoleAssignments -eq $True }                   
                    #Get Folder permissions
                    foreach($folder in $UniqueFolders)
        {
                        $FolderPermissions = Get-PermissionInfo $ClaimsUserID $folder

      #Export Folder permission data to CSV file - Append
      $FolderPermissions |  Export-csv $ReportPath -notypeinformation -Append   
                    }

     #Check List Items with Unique Permissions
     $UniqueItems = $List.Items | where { $_.HasUniqueRoleAssignments -eq $True }
                    #Get Item level permissions
                    foreach($item in $UniqueItems)
        {
                        $ItemPermissions = Get-PermissionInfo $ClaimsUserID $Item

      #Export List Items permission data to CSV file - Append
      $ItemPermissions |  Export-csv $ReportPath -notypeinformation -Append   
                    }
    }
  }
 }
 Write-Host Permission Report Generated successfully!
}

#Input Variables
$WebAppURL = "http://intranet.crescent.com"
$Userid ="Crescent\Salaudeen"
$ReportPath = "D:\Reports\PermissionRpt.csv"

#Call the function to generate user access report
Generate-PermissionReport $Userid $WebAppURL $ReportPath
4
  • Does that script work with SharePoint Online or just on-premises? – Tenttu Mar 27 '15 at 8:59
  • 1
    Unfortunately No! Its written for SharePoint 2013/2010 On-Premises only – Manish Oswal Mar 27 '15 at 9:08
  • 1
    Ok that's what I thought too and we are using SharePoint Online. Still thank you for your information! :) – Tenttu Mar 27 '15 at 10:03
  • 1
    Just for the record, PowerShell for SharePoint and PowerShell for SharePoint online are 2 VASTLY different beasts. Mostly, everything is incompatible. For SharePoint online, you want to look into PNP-Powershell: github.com/SharePoint/PnP-PowerShell – OneOfThePetes Mar 14 '19 at 11:26
0

OK, I am not very detailed knowledgeable about SharePoint. Access the top-level, main home page, of a site collection. Click on "Sites" or "Site Contents". Scroll down a little until you see "subsites". From that point on the SharePoint sites you will see are the SP sites that you have access to.

You do not see the Groups you are in, the permissions you have or any subsites of a subsite you can access either. Strictly what SharePoint subsite you can access. That is how it works where I work.

0

Try this easy way on a web browser:

Login as SP site collection Admin. Use below url with required user email and site colelction url.

https://yoursite.sharepoint.com/_api/web/SiteUsers/getByEmail('Employee.Email@domain.com')/Groups

Hit enter. Search for 'd:Title' to get SP group names. Search for 'd:Id' to get SP group ID.

To view the SP group membership, use the below url: https://yoursite.sharepoint.com/_layouts/15/people.aspx?MembershipGroupId=d:Id

Replace with your site url and SP group d:Id

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.