How to Determine Where a User Has Been Granted Access in SharePoint 2010
This post is going to discuss how to determine where a user has been granted access to your SharePoint environment. The script I provide is scoped to an individual web application and searches for all users based on their domain. I'll explain why I did that below. Both of these elements could easily be modified to suit your purposes – such as searching for a single user account across all web applications in the farm.
Background
I was recently working with a customer who had discovered a configuration issue in their farm. The environment has two domains. In their particular case, a two-way trust was required and had been enabled. Only users from one specific domain were intended to have access to the SharePoint environment. Two elements of oversight resulted in users of the other domain having access to the site. The first oversight is that the people picker had not been scoped to only one domain. This can be configured using the following article: Peoplepicker-searchadforests: Stsadm property (Office SharePoint Server). I do realize that the documentation specifies SharePoint 2007, however it is also applicable for SharePoint 2010, as indicated in this article: People Picker overview (SharePoint Server 2010). The next issue is that people had also been granting access to 'NT Authority\Authenticated User', which includes users authenticated to both domains.
Approach
The approach I'm taking is a series of enumerations. Permissions are applied at the web, list, and object level, so we need to find a way to get all the way down there. First we need to enumerate all site collections, and all webs in those site collections, then all lists in those webs, finally we could enumerate all list items in those lists as well.
For the purposes of this sample script and this blog post, I've chosen to go only as far as the individual lists. The approach you would take to report on individual list items would be effectively the same, including one additional enumeration for all list items in each list.
Once we have a list of all these webs and lists, we need to find a way to find out who has been granted access to the item, and how they have been granted access to that item.
Solution
Now that we know the approach, the solution is pretty simple. The first thing that you have to do is enumerate through site collections. Getting a list of all site collections can be accomplished using Get-SPSite.
As I said, we're going to be enumerating through them and performing some additional actions. For that, I've chosen to create some ForEach-Object loops.
User security is applied not at the site level, but at the web level. Which means we actually need to get a list of all webs in all sites. This can be placed inside the first ForEach loop. What we'll be doing is using the SPSite object's AllWebs property.
If a web is not using unique security, then it will be inheriting from the parent. This means we don't need to check roles on that object. But first we need to find out how to do that for each web. PowerShell again makes this very simple, because every web has a HasUniqueRoleAssignments property. This property will tell us if the site uses unique permissions or not.
Once we've determined if the web has unique role assignments, we can start looking for what those role assignments are. There are two places to look for. Users who have been assigned permissions directly, and users who have been added to SharePoint groups. PowerShell again makes gives us a break. To discover each user who has been assigned permission directly, use the RoleAssignments property of the Web object.
In order to discover users who have been granted permission through groups, this is a little more difficult – but not much. From the RoleAssignments from the web, we have a list of users and a list of SharePoint groups. We can enumerate the members of all group objects by calling the users property of the members property of the RoleAssignments property for the web. This may be getting a little complicated, but I've included a screenshot below. In this screenshot, we can see that two accounts have been granted full control because they are members of the SharePoint Owners group.
This has gotten us as far as enumerating all webs where unique permissions have been applied. So how do we do this for lists? It's effectively exactly the same. Each Web object has a Lists property.
Another great thing about PowerShell in SharePoint, every single list object has a RoleAssignments property, just like webs.
In order to return users who have been explicitly granted access, or who have been granted access via a SharePoint group, you would use the same script as you did for the web object.
As I mentioned, the sample script I'm providing currently looks for users from a particular domain. It would take very little effort to transform this script and search for specific user accounts. If I get any requests for it, I may just add it as a secondary download from this blog post.
Download This Script
Download SecurityReport.ps1 (zipped)
Usage
There are three variables which need to be altered before running this script. Failing to alter them may result in the script not running, or producing useless data. One is the web application URL, one is the unwanted domain prefix, and one is the log file directory where the output will be generated.
Feedback
As always, if you have any questions or feedback, let me know. If you have any ideas to optimize the script, I'd like to hear that too. Thanks for reading!
You can also follow me on Twitter:
Comments
Anonymous
October 25, 2012
This is be very useful, thanks for sharing. It would beneficial if you could also add the script for returning details of specific user accountsAnonymous
October 29, 2012
The comment has been removedAnonymous
October 29, 2012
Nice one.. thanks!Anonymous
November 05, 2012
The comment has been removedAnonymous
November 05, 2012
Thanks for the feedback everyone. I could probably put a sample report up on Galleries - just include what the output looks like so people know what they're getting into. I should probably clean it up a little bit and output it to CSV or something though if people are actually going to use it. I'll come back to that once I get a few more things I'm working on published.Anonymous
November 19, 2012
Also, Craig. Thanks for the heads-up. I've gone ahead and updated my script as well to patch against that condition.Anonymous
December 10, 2012
The comment has been removedAnonymous
January 14, 2013
Also agree...a csv version would be awesome.Anonymous
January 15, 2013
The comment has been removedAnonymous
October 21, 2013
Hi , How can I modify into a script to check what all kind of permission a user has on the complete site collection. User input will be the username .Anonymous
December 18, 2013
will this work on SharePoint 2013?Anonymous
December 18, 2013
As far as I can see by looking through the script, there's nothing I'm using that has changed for SharePoint 2013 , so this should work.Anonymous
December 18, 2013
Will this work on SP 2013?Anonymous
December 18, 2013
The comment has been removedAnonymous
March 18, 2014
Works nicely, how much would it take to get it to work for a single username?Anonymous
March 20, 2014
Thanks! Add me to the list of people asking to work for a single username.Anonymous
May 07, 2014
This is a great script. how could I also identify the ACL and then transfer over from AD to SP? If that's asking to much.Anonymous
July 22, 2014
$WebRoleAssignment.member.userlogin Property 'userlogin' cannot be found on this object. Make sure that it exists. Anyone have any ideas?Anonymous
September 01, 2014
Thanks for the script! It would be really great that we could check only one username where it has access in all web applications and site collections.Anonymous
November 05, 2014
I can only encourage you (as some users already mentioned) to provide script where we get access details for specific usernamesAnonymous
November 20, 2014
Is there a simple modification I can make to this script where I can find everywhere a domain exists, add a new domain, then delete the old one? We basically need to search for two different AD/Domains, then add a new one/delete the old ones.Anonymous
January 07, 2015
For 2013 I'm getting the list of Webs but not eh actual list of users and permissions. This ran fine on my 2010 farm. Any ideas? Thanks!Anonymous
March 17, 2015
good One..ThanksAnonymous
January 20, 2016
This script is brilliant, made my day. Worked first time and I can finally see who can see what all over my server. Thanks a million!