Check folder permissions remotely via PowerShell

Below you can find script for checking permissions remotely using Get-ACL command. Sometimes you need to determine what permissions are defined on specific folder in your entire environment. Of course you will not do that manually 🙂

Get-ACL
Get-ACL

The Get-Acl cmdlet enables you to retrieve the security descriptor (access control list) for a file, a folder, or even a registry key. An access control list (ACL), with respect to a computer file system, is a list of permissions attached to an object. To get permissions locally you just need to specify for example folder path and run the following command:

$Path = "C:\users\$env:username\desktop"
Get-Acl $Path | Select -ExpandProperty Access | Where-Object {$_.PropagationFlags -match "InheritOnly"}
#or
Get-Acl $Path | Select -ExpandProperty Access

In this function we also need to use Switch to translate values from FileSystemRights into readable data:

Switch ($item.FileSystemRights)
{
   "2032127"     { $Val = "FullControl" }
   "1179785"     { $Val = "Read" }
   "1180063"     { $Val = "Read, Write" }
   "1179817"     { $Val = "ReadAndExecute" }
   "-1610612736" { $Val = "ReadAndExecuteExtended" }
   "1245631"     { $Val = "ReadAndExecute, Modify, Write" }
   "1180095"     { $Val = "ReadAndExecute, Write" }
   "268435456"   { $Val = "FullControl (Sub Only)" }
}

Usage:

Get-Permissions -Servers DC01 -Path "C:\WINDOWS"
Get-Permissions -Servers DC01,DC02 -Path "C:\WINDOWS"
Get-Permissions -Servers (GC "C:\Temp\servers.txt") -Path "C:\WINDOWS"
Get-Permissions -Servers (GC "C:\Temp\servers.txt") -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Group Policy"

Final script:


Function Get-Permissions{
    [CmdletBinding()]        
      
    # Parameters used in this function
    param
    (
        [Parameter(Position=0, Mandatory = $True, HelpMessage="Provide server names", ValueFromPipeline = $true)] 
        $Servers,
   
        [Parameter(Position=1, Mandatory = $False, HelpMessage="Provide path, for example c:\users", ValueFromPipeline = $true)]
        $Path
    ) 
 
    $Array = @()
    #$Cred = Get-Credential $env:Username

    If(!$Path)
    {
        Write-Warning "Script ends: Path has not been provided"
    }
    Else
    {
        # Loop through the servers
        ForEach($Server in $Servers)
        {
            Try
            {
                #$ACLs = Invoke-Command $Server -ErrorAction Stop -ScriptBlock{param($Path)Get-Acl $Path | Select -ExpandProperty Access | Where-Object {$_.PropagationFlags -match "InheritOnly"}} -ArgumentList $path #-Credential $cred
                $ACLs = Invoke-Command $Server -ErrorAction Stop -ScriptBlock{param($Path)Get-Acl $Path | Select -ExpandProperty Access } -ArgumentList $path #-Credential $cred
            }
            Catch
            {
                $_.Exception.Message
                Continue
            }
    
                If($ACLs)
                {
                    # Loop each ACL
                    $ACLs | ForEach-Object {
    
                        # Define current loop to variable
                        $item = $_
    
                        Switch ($item.FileSystemRights)
                        {
                            "2032127"     { $Val = "FullControl" }
                            "1179785"     { $Val = "Read" }
                            "1180063"     { $Val = "Read, Write" }
                            "1179817"     { $Val = "ReadAndExecute" }
                            "-1610612736" { $Val = "ReadAndExecuteExtended" }
                            "1245631"     { $Val = "ReadAndExecute, Modify, Write" }
                            "1180095"     { $Val = "ReadAndExecute, Write" }
                            "268435456"   { $Val = "FullControl (Sub Only)" }
                        }

                        $Object = New-Object PSObject -Property @{ 
  
                            Servername             = $Server
                            Path                   = $Path
                            FileSystemRights       = $val      
                            Access                 = $Item.AccessControlType
                            Identity               = $Item.IdentityReference           
                            IsInherited            = $Item.IsInherited
                            PropagationFlags       = $item.PropagationFlags                    
  
                        }
               
                        # Add custom object to our array
                        $Array += $Object
                    }
                }
        }
    }

    If($Array)
    {
        Write-Host "`nPermissions for $Path" -ForegroundColor Green
        $Array | Select-Object Servername,Path,Access,FileSystemRights,Identity,IsInherited,PropagationFlags | Format-Table -AutoSize

        # Results in pop-up window
        $Array | Select-Object Servername,Path,Access,FileSystemRights,Identity,IsInherited,PropagationFlags | Out-GridView -Title "Permissions for $Path"
    }
}

For more information about Get-ACL command please visit link.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.