Windows – HALP! I’ve inherited a permissions nightmare for redirected folders/home directories

active-directoryfolder-redirectionhome-directorypowershellwindows

My new employer has folder redirection setup for its hundreds of users, and the person who set it up didn't really know what he was doing. As a result, the best practices for permissions on redirected folders/home directories was not followed.

The solution to let people access their redirected folder locations was to instead apply Full Control permissions (NTFS permissions, not "share" permissions, of course) to Everyone at the root directory ("Home") and propagate that down to all subfolders and files below the root.

What could possibly go wrong, right? It's not like the CEO has confidential information in his My Documents folder, or anyone's going to get infected with CryptoWall and encrypt everyone else's files. Right?

So, anyway, now that the CryptoWall infection has been removed and backups have been restored, a number of people would like us to replace the current permissions with something less horrible, and I would like to not have to click around the permissions dialogues in several hundred folders.

How can PowerShell solve this problem for me, and make life worth living again?

Best Answer

With thanks to JScott for referring me to the System.Security.Principal... class or method or whatever it is, some PowerShell to replace the ACLs on a bunch of subfolders with those that are appropriate for user home directories:

$Root = "Path to the root folder that holds all the user home directories"

$Paths = Get-ChildItem $Root | Select-Object -Property Name,FullName

$DAAR = New-Object system.security.accesscontrol.filesystemaccessrule("MyDomain\Domain Admins","FullControl","ContainerInherit, ObjectInherit","None","Allow")
#Domain Admin Access Rule.

$SysAR = New-Object system.security.accesscontrol.filesystemaccessrule("SYSTEM","FullControl","ContainerInherit, ObjectInherit","None","Allow")
#SYSTEM Access Rule.

foreach ($Folder in $Paths)
{

    Write-Host "Generating ACL for $($folder.FullName) ... "
    #For error handling purposes - not all folders will map to a user of the exact same name, this makes them easier to handle when viewing the output.

    $ACL = New-Object System.Security.AccessControl.DirectorySecurity
    #Creates a blank ACL object to add access rules into, also blanks out the ACL for each iteration of the loop.

    $objUser = New-Object System.Security.Principal.NTAccount("MyDomain\​"+$folder.name)
    #Creating the right type of User Object to feed into our ACL, and populating it with the user whose folder we're currently on.

    $UserAR = New-Object system.security.accesscontrol.filesystemaccessrule( $objuser ,"FullControl","ContainerInherit, ObjectInherit","None","Allow")
    #Access Rule for the user whose folder we're dealing with during this iteration.

    $acl.SetOwner($objUser)
    $acl.SetAccessRuleProtection($true, $false)
    #Change the inheritance/propagation settings of the folder we're dealing with

    $acl.SetAccessRule($UserAR)
    $acl.SetAccessRule($DAAR)
    $acl.SetAccessRule($SysAR)

    Write-Host "Changing ACL on $($folder.FullName) to:"
    $acl | fl
    #For error handling purposes - not all folders will map to a user of the exact same name, this makes them easier to handle when viewing the output.

    Set-Acl -Path $Folder.Fullname -ACLObject $acl

}