Windows NTFS – Add permission to each explicit ACL in all subfolders

file-permissionsntfswindows

We have a folder structure with many explicit rights like

root Folder
- subfolder 1 (explicit acl, no inherit acl)
- subfolder 2 (explicit acl, no inherit acl)
--subsubfolder 1 (no explicit rights, inherit acl)
--subsubfolder 2 (explicit acl, no inherit acl)

and so on

I want to add a permission (System Account) to all explicit ACLs but not to those which are not explicit. And of course there are some Folders which are not accessible even by an Administrator account, so I need to ignore Errors.

Anyone aware of an script which can achieve this?

Edit1
Thanks to Hardoman, here is a working solution for current folder, subfolder and files and without catching the error…

$folders = (Get-ChildItem C:\Temp -Directory -Recurse) | select -ExpandProperty fullname
foreach ($item in $folders) {
    $inheritance = (Get-Acl $item).access[0] | select -ExpandProperty isinherited
    if ($inheritance -eq $false) {
            icacls.exe $item /grant 'System:(OI)(CI)(RX)'
    }
}

Didn`t found a solution with set-acl, maybe someone has an idea, this is my current set-acl state but the subfolder dont get the permissions even when they are inherited.

$folders = (Get-ChildItem C:\Temp -Directory -Recurse) | select -ExpandProperty fullname
foreach ($item in $folders) {
    $inheritance = (Get-Acl $item).access[0] | select -ExpandProperty isinherited
    if ($inheritance -eq $false) {
    try {
        $acl = Get-Acl $item
        $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("System","FullControl, Synchronize", "ContainerInherit,ObjectInherit", "None", "Allow")
        $acl.SetAccessRule($AccessRule)
        Set-Acl $item $acl
    }
    catch {
        "Failed to access folder $item"
        "Exception type is $($_.Exception.GetType().Name)"
        }
    }
}

Best Answer

You need to write a Powershell script for that. You need to recursively get all folders and subfolders, check inheritance for each and using Get-ACL and Set-ACL commadlets add permissions for the system account. Try/catch will handle the errors in case script can't access the folder.

Here is the sample I wrote for you assuming that you recurse in C:\temp folder as an example.

$folders = (Get-ChildItem c:\temp -Directory -Recurse) | select -ExpandProperty fullname
foreach ($item in $folders) {
    $inheritance = (Get-Acl $item).access[0] | select -ExpandProperty isinherited
    if ($inheritance -eq $false) {
    try {
        $acl = Get-Acl $item
        $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ("System","FullControl","Allow")
        $acl.SetAccessRule($AccessRule)
        $acl | Set-Acl $item
    }
    catch {
        "Failed to access folder $item"
        "Exception type is $($_.Exception.GetType().Name)"
        }
    }
}

P.S. For Get-ChildItem with -Directory to work you need to have Powershell 4+. This switch is missing in PS 2.0

Related Question