[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 294
  • Last Modified:

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

0
CCtech
Asked:
CCtech
  • 3
  • 3
1 Solution
 
Gerwin Jansen, EE MVETopic Advisor Commented:
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
0
 
CCtechAuthor Commented:
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.
0
 
CCtechAuthor Commented:
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.
0
 The Evil-ution of Network Security Threats

What are the hacks that forever changed the security industry? To answer that question, we created an exciting new eBook that takes you on a trip through hacking history. It explores the top hacks from the 80s to 2010s, why they mattered, and how the security industry responded.

 
Gerwin Jansen, EE MVETopic Advisor Commented:
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).
0
 
CCtechAuthor Commented:
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?
0
 
Gerwin Jansen, EE MVETopic Advisor Commented:
You want your remove domain users that have read access to all home folders? In your question you say: "it does not remove the domain users group, which also has full access."

Anyway: I'd just remove all domain users' access rules, like this:

# reportmode is off, fix the permissions
$yAcl=$Acl.GetAccessRules($true, $true, [System.Security.Principal.NTAccount])
foreach($Rule in $yAcl) {
if ($Rule.IdentityReference.Value -eq "Domain Users") {
  $acl.RemoveAccessRule($Rule)
  }
}

Create one test folder, give Domain Users full control and test the modified script.
0

Featured Post

A Cyber Security RX to Protect Your Organization

Join us on December 13th for a webinar to learn how medical providers can defend against malware with a cyber security "Rx" that supports a healthy technology adoption plan for every healthcare organization.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now