Link to home
Start Free TrialLog in
Avatar of CCtech
CCtechFlag for United States of America

asked on

Resetting Home Drive Permissions PS Script

I have another client with messed up home drive permissions. The root folder had domain users - read / write NTFS permissions, so when ever a users home folder was created, it also inherited this permission. So, everyone on the domain has access to everyone's home drives. I have run in to this issue in the past, and found this script a while back (see below) which works wonders. It goes through and grants full access permissions for each user, on their own folder. The problem is, it does not remove the domain users group, which also has full access. Is there something I can add to take care of this?

The only other way which I have done before is to set the NTFS permissions on the root folder containing the home drive folders so that only domain admins have full access, no other permissions are set. Sharing is to everyone, as it should be. Then, I check the box to replace all child items, so each home drive folder has the same permissions as the root - domain admins only, then I run the script and it adds each user the proper permissions to their folder.

The problem with this method is it takes forever, there is close to a TB of data in this folder and will take an incredibly long time. Also, Users in this company access this data all throughout the week, including weekends, so for a moment of time they will loose access.

I also posted in a Technet forum and a user said this could be fixed via group policy, but did not recommend any method to do so.

Any ideas?




############################################################################
# Script: Repair-HomeFolderPermissions.ps1
# Author: Chris Brown    http://www.flamingkeys.com
# Date: 20/10/2010
# Keywords:
# Comments:
# Pre-Requisites: Full Control over destination folder.
#
# +------------+-----+---------------------------------------------------------+
# |       Date | Usr | Description                                             |
# +------------+-----+---------------------------------------------------------+
# | 20/10/2010 | CJB | Initial Script                                          |
# | 28/09/2011 | CJB | Fixed flags issue                                       |
# +------------+-----+---------------------------------------------------------+
#
# DISCLAIMER
# ==========
# THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
# RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#############################################################################

# ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
#            Variables
#
# Where is the root of the home drives?
$homeDrivesDir="F:\Data\HomeDrives"
# Report only? ($false = fix problems)
$reportMode = $false
# Print all valid directories?
$verbose = $false
# What domain are your users in?
$domainName = "mydomiain.local"
#
# ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

# Save the current working directory before we change it (purely for convenience)
pushd .
# Change to the location of the home drives
set-location $homeDrivesDir

# Warn the user if we will be fixing or just reporting on problems
write-host ""

if ($reportMode) {
 Write-Host "Report mode is on. Not fixing problems"
} else {
 Write-Host "Report mode is off. Will fix problems"
}

write-host ""

# Initialise a few counter variables. Only useful for multiple executions from the same session
$goodPermissions = $unfixablePermissions = $fixedPermissions = $badPermissions = 0
$failedFolders = @()

# For every folder in the $homeDrivesDir folder
foreach($homeFolder in (Get-ChildItem $homeDrivesDir | Where {$_.psIsContainer -eq $true})) {

 # dump the current ACL in a variable
 $Acl = Get-Acl $homeFolder

 # create a permission mask in the form of DOMAIN\Username where Username=foldername
 #    (adjust as necessary if your home folders are not exactly your usernames)
 $compareString = "*" + $domainName + "\" + $homeFolder.Name + " Allow  FullControl*"

 # if the permission mask is in the ACL
 if ($Acl.AccessToString -like $compareString) {

 # everything's good, increment the counter and move on.
 if ($verbose) {Write-Host "Permissions are valid for" $homeFolder.Name -backgroundcolor green -foregroundcolor white}
 $goodPermissions += 1

 } else {
 # Permissions are invalid, either fix or report
 # increment the number of permissions needing repair
 $badPermissions += 1
 # if we're in report mode
 if ($reportMode -eq $true) {
 # reportmode is on, don't do anything
 Write-Host "Permissions not valid for" $homeFolder.Name -backgroundcolor red -foregroundcolor white
 } else {
 # reportmode is off, fix the permissions
 Write-Host "Setting permissions for" $homeFolder.Name -foregroundcolor white -backgroundcolor red
 # Add the user in format DOMAIN\Username
 $username = $domainName + "\" + $homeFolder.Name
 # Grant the user full control
 $accessLevel = "FullControl"
 # Should permissions be inherited from above?
 $inheritanceFlags = "ContainerInherit, ObjectInherit"
 # Should permissions propagate to below?
 $propagationFlags = "None"
 # Is this an Allow/Deny entry?
 $accessControlType = "Allow"
 try {
 # Create the Access Rule
 $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($username,$accessLevel,$inheritanceFlags,$propagationFlags,$accessControlType)

 # Attempt to apply the access rule to the ACL
 $Acl.SetAccessRule($accessRule)
 Set-Acl $homeFolder $Acl
 # if it hasn't errored out by now, increment the counter
 $fixedPermissions += 1
 } catch {
 # It failed!
 # Increment the fail count
 $unfixablePermissions += 1
 # and add the folder to the list of failed folders
 $failedFolders += $homeFolder
 }
 } #/if
 } #/if
} #/foreach

# Print out a summary

Write-Host ""
Write-Host $goodPermissions "valid permissions"
Write-Host $badPermissions "permissions needing repair"
if ($reportMode -eq $false) {Write-Host $fixedPermissions "permissions fixed"}
if ($unfixablePermissions -gt 0) {
 Write-Host $unfixablePermissions "ACLs could not be repaired."
 foreach ($folder in $failedFolders) {Write-Host " -" $folder}
}

# Cleanup
popd

Open in new window

Avatar of Gerwin Jansen
Gerwin Jansen
Flag of Netherlands image

In line #99 the script is setting the new acl entry for the domain user. That acl variable was previously filled with the current acl in line #60 The acl is then applied in line #100

So you can do one of 2 things:
- remove the Domain Users entry from the Acl variable before the Acl is applied
- create a new empty Acl variable that will only get the correct acl entry for the user
Avatar of CCtech

ASKER

Thanks for the help. I ended up using icacls to break inheritance and remove the domain users group from each folder, which worked like a charm.

icacls "F:\users\*" /inheritance:d /remove "domain.local\domain users" /t

Running this command after running the PS script corrects all permissions for all home folders.
Avatar of CCtech

ASKER

I've requested that this question be closed as follows:

Accepted answer: 0 points for Walter White's comment #a40252002

for the following reason:

Someone over on spiceworks recommended this solution and it worked.
I'm objecting to the way you are closing this question, I'm suggesting to do this:

"- remove the Domain Users entry from the Acl variable before the Acl is applied"

And you've solved the issue by doing just that, only with a different command (icacls).
Avatar of CCtech

ASKER

Gerwin, I understand that what you suggested will accomplish the same goal. Can you help me include this in to the code? I believe I have it correct, but want to verify. I have added a few lines to define $accessrule2, remove access, and apply.

# Create the Access Rule
 $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($username,$accessLevel,$inheritanceFlags,$propagationFlags,$accessControlType)
 $accessrule2 = New-Object system.security.AccessControl.FileSystemAccessRule("domain.local\domain users","Read",,,"Allow")

 # Attempt to apply the access rule to the ACL
 $Acl.SetAccessRule($accessRule)
 $acl2.RemoveAccessRuleAll($accessrule2)
 
 Set-Acl $homeFolder $Acl
 Set-Acl $homeFolder $Acl2

Open in new window



Does this look correct to you?
ASKER CERTIFIED SOLUTION
Avatar of Gerwin Jansen
Gerwin Jansen
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial