Who’s got access to this directory?

This is a guest post by Tom. He regularly posts at www.workingsysadmin.com/

I frequently field requests along the lines of “Please provide a list of everybody who has access to xyz directory” which, in itself, is a pretty simple request to get your head around. If you’re following best practices, when you provision access to an area of your file system, you give the permissions to an Active Directory group and throw people into that group as needed. Where these requests turn into a PITA is when you start throwing groups into these groups and sometimes these groups have nested groups inside them and by the time you find an actual user, you’re six groups deep. If only there was some way to use PowerShell to get this information for you! Well there is and it’s easy. The solution I’m going to share assumes you’ve installed Quest AD cmdlets and it doesn’t talk about error checking that much because you can probably figure that out yourself. First things first, you’re going to want to add the QAD items to your session.

add-pssnapin quest.activeroles.admanagement 


Crazy, right? Let’s also set a couple other variables to make the rest of this easier.

$strDirectory = "Z:\some\directory" #the directory we want to audit
$strOutFile = "C:\temp\results.txt" #the file we're going to stick our results in
$ErrorActionPreference = "silentlycontinue" #I told you that you're on your own for errors

Now if life was easy, or someone was sloppy and just assigned permissions to users directly instead of following best practices, you could just perform a Get-ACL command on the directory and extract some information out of it like this.


$aclDirectoryACL = get-acl $strDirectory
$arrDirectoryAccess = @($aclDirectoryACL.access)
$arrIdentityReference = $arrDirectoryAccess | select-object IdentityReference
$arrUsers = $identref | % { if ($_.arrIdentityReference.value -ne "ABCP\Domain Admins") {$_.arrIdentityReference.value} }
$arrUsers | select-object name | out-file -append $strOutFile

What we’re doing is getting the Access Control List (ACL) for the directory we’re looking at, extracting the Access component of the ACL and looking at all the identities of the objects with access. Effectively, we’re getting all the information on access associated with the directory, narrowing our scope to objects and their permissions, then narrowing once more just to the identities of these objects. Once we have the identities in an array, I’m recording the ones that aren’t Domain Admins since I don’t want to report on Domain Admins. Awesome! Now what if you do follow best practices? This list would come back with a bunch of groups instead of their members. Well what if you could change that second last line to something like this.


$arrUsers = $identref | % { if ($_.arrIdentityReference.value -ne "ABCP\Domain Admins") {$_.arrIdentityReference.value} } | % { get-nestedgroupmember $_ }

Get-NestedGroupMember? That looks awesome. Hold on, that function doesn’t exist in QAD tools. Well I guess we’re going to have to write it ourselves, then. First, though, let’s think about what we want it to do. We want to see if the item we’re looking at is a group or a user. If it’s a user, return the user and if it’s a group, we want to recursively call the same function to go deeper until we start getting some users. Sounds easy enough, right? That’s because it is.


Function Get-NestedGroupMember($strGroup) {
Get-QADGroupMember $strGroup | foreach{
if($_.type -eq "group"){Get-NestedGroupMember($_)}
else {$_}}
}

Boom. Get the group members for the group we passed it and keep checking if that group has groups in it. Here’s what the whole thing looks like.


add-pssnapin quest.activeroles.admanagement

$strDirectory = "Z:\some\directory" #the directory we want to audit
$strOutFile = "C:\temp\results.txt" #the file we're going to stick our results in
$ErrorActionPreference = "silentlycontinue" #I told you that you're on your own for errors

Function Get-NestedGroupMember($group) {
Get-QADGroupMember $group | foreach{
if($_.type -eq "group"){Get-NestedGroupMember($_)}
else {$_}}
}

$aclDirectoryACL = get-acl $strDirectory
$arrDirectoryAccess = @($aclDirectoryACL.access)
$arrIdentityReference = $arrDirectoryAccess | select-object IdentityReference
$arrUsers = $identref | % { if ($_.arrIdentityReference.value -ne "ABCP\Domain Admins") {$_.arrIdentityReference.value} } | % { get-nestedgroupmember $_ }
$arrUsers | select-object name | out-file -append $strOutFile

There’s lots of ways to accomplish the same thing but this is what I came up with in a moment of need and figured I might as well share it.   Like this post? Follow me on Twitter at @ThmsRynr or connect with me on LinkedIn.

Advertisements

2 thoughts on “Who’s got access to this directory?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s