powershellpermissionsaclicacls

Replace permissions with icacls.exe


We have a lot of folders with the following permissions:

PS C:\> icacls.exe C:\Temp\Test
C:\Temp\Test    BUILTIN\Administrators:(OI)(CI)(F)
                NT AUTHORITY\SYSTEM:(OI)(CI)(F)
                DOMAIN\USER:(OI)(IO)(RX)
                DOMAIN\USER:(CI)(RX) 

We would like to replace the two permissions from DOMAIN\USER to one with (OI)(CI)(RX).
To achive that, we used icacls.exe /grant:r. Unfortunately the :r parameter does not work.

PS C:\> icacls.exe --% C:\Temp\Test /grant:r DOMAIN\USER:(OI)(CI)(RX)
PS C:\> icacls.exe C:\Temp\Test
C:\Temp\Test    BUILTIN\Administrators:(OI)(CI)(F)
                NT AUTHORITY\SYSTEM:(OI)(CI)(F)
                DOMAIN\USER:(OI)(IO)(RX)
                DOMAIN\USER:(CI)(RX)
                DOMAIN\USER:(OI)(CI)(F)

As you can see, the permission was added and not replaced. Is there a way to replace the permissions with icacls.exe?


Solution

  • cacls.exe provides the parameter /P to achieve the replacement (see here).

    cacls.exe C:\Temp\Test /E /P DOMAIN\USER:F
    

    This one would work but then I struggled about the special permissions (DOMAIN\USER2:(OI)(CI)(IO)(M))

    So I wrote some PowerShell code to achieve the same with icacls.exe.
    Before granting the new explicit permission, the old one will be removed with /remove:g.

    $FolderPath = 'C:\Temp\Test'
    $NewPermission = @('DOMAIN\USER1:(OI)(CI)(F)', 'DOMAIN\USER2:(OI)(CI)(RX,W)', 'DOMAIN\USER2:(OI)(CI)(IO)(M)')
    
    $IcaclsOutput = icacls.exe "$FolderPath"
    $InheritedPermission = @()
    $InheritedPermission = foreach ($Line in $IcaclsOutput)
    {
        #Check if last line
        if ($Line -eq '')
        {
            break
        }
    
        #Get inherited permissions
        $Permission = ''
        $Permission = $Line.Substring($FolderPath.Length + 1, $Line.Length - ($FolderPath.Length + 1))
        if ($Permission -notlike '*(I)*')
        {
            $Permission.Split(':')[0]
        }
    }
    
    $InheritedPermission = $InheritedPermission | Sort-Object -Unique
    
    #Set new permission
    if ($InheritedPermission.Count -ne 0)
    {
        #Remove granted explicit permissions and add new on 
        icacls.exe "$FolderPath " /remove:g ($InheritedPermission) /grant:r ($NewPermission)
    }
    else
    {
        #Add new one
        icacls.exe "$FolderPath " /grant:r ($NewPermission)
    }