Find Folders a user has access to

Tagged: , ,

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Rohn Edwards Rohn Edwards 2 years, 2 months ago.

  • Author
    Posts
  • #18734
    Profile photo of NetAdminTX
    NetAdminTX
    Participant

    Ok , I have pieced together the following script but I am not getting any output
    the goal of this script is to take input (username, and base folder path), then check all folders in the directory path – recursively looking for folders that the user has access to
    I want to then output the listing of folders and access to the screen (eventually we will redirect this to a file, but I need to see it working on the screen first)
    I also need to expand this script to also look for any groups that the user may be a member of...
    any help would be greatly appreciated ( I will admit some of this code comes from the internet)

    # This script will pull back the folders that a specific user has access to
    # Written by
    # Initial coding – 2014-09
    #
    #
    #Get base folder path
    $basefolder = read-host "Enter Directory Tree Starting Point (script is recursive)"
    #Get username
    $usertocheck = read-host "Enter The Username To Check For Access (Do Not Include Domain Name)"
    #
    #create folders list
    $folders = get-childitem $basefolder -recurse -directory |foreach-object {$_.fullname}
    #
    #Create ACL Shortcut
    $acls = get-acl -path $folders
    #
    #Create Outpout object for later user
    $outputObject = @()
    #
    #Foreach($acl in $acls)
    {
    $folder = (convert-path $acl.pspath)
    Write-Progress -act "Getting Security" -status "checking $folder" -percent ($i/ $folders.count*100)
    #creates new array for later output
    $object = New-Object -TypeName PSObject
    Foreach($access in $acl.access)
    {
    Foreach($value in $access.identityReference.Value)
    {
    if ($value -eq $usertocheck)
    {
    $object | Add-Member -MemberType NoteProperty -Name Folder -Value $folder
    $object | Add-Member -MemberType NoteProperty -Name user -Value $user
    $object | Add-Member -MemberType NoteProperty -Name mode -Value $access.AccessControlType
    $outputObject += $object
    }
    } #end foreach value
    } # end foreach access
    $1++
    } #end Foreach acl
    #write outputobject to screen
    write-host $outputObject

  • #18738
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Are you only looking for folders that the user has been directly granted access to, or are you interested in permissions granted via group memberships as well? Your code currently looks more like the former, looking only for access entries applied directly to the user.

    However, your main problems are that right now you've commented out your foreach ($acl in $acls) line (which is the only place the $acl variable is set), and you're also comparing the raw user input ($usertocheck) to IdentityReference.Value properties, which may not be very reliable. You'd be better off doing some form of validation on the user input (ideally, translating it to a SID, which would guarantee that the user has entered a valid input), and then making sure that the IdentityReference you're comparing it to is also translated to a SID. For example, something along these lines might be closer to what you're trying to accomplish:

    $basefolder = read-host "Enter Directory Tree Starting Point (script is recursive)"
    
    $usertocheck = read-host "Enter The Username To Check For Access"
    $ntaccount = [System.Security.Principal.NTAccount]$usertocheck
    
    try
    {
        $sid = $ntaccount.Translate([System.Security.Principal.SecurityIdentifier])
    }
    catch
    {
        throw "Could not resolve $usertocheck to a SID: $($_.Exception.Message)"
    }
    
    $folders = get-childitem $basefolder -recurse -directory |foreach-object {$_.fullname}
    $acls = get-acl -path $folders
    
    $i = 0
    
    foreach ($acl in $acls)
    {
        $folder = (convert-path $acl.pspath)
        Write-Progress -Activity "Getting Security" -Status "checking $folder" -PercentComplete ($i/ $folders.count*100)
        
        foreach($access in $acl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]))
        {
            if ($access.IdentityReference.Value -eq $sid.Value)
            {
                [pscustomobject] @{
                    Folder = $folder
                    User = $ntaccount.Value
                    Mode = $access.AccessControlType
                }
            }
        }
    
        $i++
    }
    
    Write-Progress -Activity "Getting Security" -Completed
    
  • #18739
    Profile photo of NetAdminTX
    NetAdminTX
    Participant

    the original script I started with would only look for explicit permissions, I am interested in both explicit and permissions granted via groups.
    thanks for the quick response, and advice on checking the input
    And thanks for catching my basic mistake
    Ill update my code and test it again.

  • #18740
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Once you start getting into territory of dealing with nested group memberships and consolidating multiple ACEs to figure out effective permissions, the code can get a bit complex. While it's certainly possible to write a script to do all of that if you want to, you'd be kind of reinventing the wheel. In your shoes, I'd start looking at existing utilities for this sort of analysis, such as [url="http://technet.microsoft.com/en-ca/sysinternals/bb664922.aspx"]AccessChk[/url] from the SysInternals suite.

  • #18753
    Profile photo of Rohn Edwards
    Rohn Edwards
    Participant

    The PowerShell Access Control module will check effective access for a specified user (or users). If you're interested, try this and see if it provides part of what you're looking for:

    dir c:\FolderName -Recurse -Directory | Get-EffectiveAccess -Principal UserName
    

You must be logged in to reply to this topic.