Powershell Script Help

Associate
Joined
2 Aug 2005
Posts
589
What I'm wanting to achieve is a script that sets the following permissions on the root of a share:

Domain Admin: Full control, folders, subfolders and files

Domain Users: This folder only, read and traverse.

Once the script is set, I want it to match the user folders (in the same format as their AD user account) and give them full control over their own folder, subfolders and files.

Unfortunately I'm having a number of issues (mostly around the set-acl section). Can someone help please?

Code:
#Fix Home folder Permissions v1.0

#-------------------Editable Variables----------------------#

# Where is the root of the home drives?
$homeDrivesDir=""
# Report only? ($false = fix problems)
$reportMode = $false
# Print all valid directories?
$verbose = $false
# What domain are your users in?
$domainName = ""

$homeFolders = Get-ChildItem $homeDrivesDir | Where {$_.psIsContainer -eq $true}

#--------------------User Inputs-----------------------------#

$homeDrivesDir = Read-Host "Please type the name of the share, e.g \\SERVER\SHARE\. Please include the trailing \"
$domainName = Read-Host "Please enter the domain name"

#------------------Share Permissions-------------------------#

    # Put the permissions of the share into a variable
    $homeDrivesDiracl = Get-Acl $homeDrivesDir

    #Removes all access to share
    $homeDrivesDiracl.Access | %{$homeDrivesDiracl.RemoveAccessRule($_)}

    #Puts Domain admin permissions into a variable
    Write-Host "Setting permissions for" $homeDrivesDir "Share" -foregroundcolor white -backgroundcolor red
    # Add the domain admin into the $username variable
    $username = "domain\domain admins"
    # 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"

    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($username,$accessLevel,$inheritanceFlags,$propagationFlags,$accessControlType)

    #Applies above variable to top-level folder

    $homeDrivesDiracl.SetAccessRule($accessRule)
    Set-Acl -path $homeDrivesDir $homeDrivesDiracl

    # Add the domain users into the $username variable
    $username = "domain\domain users"
    # Grant the user full control
    $accessLevel = "ReadandExecute"
    # Should permissions be inherited from above?
    $inheritanceFlags = "None, None"
    # Should permissions propagate to below?
    $propagationFlags = "None"
    # Is this an Allow/Deny entry?
    $accessControlType = "Allow"

    $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($username,$accessLevel,$inheritanceFlags,$propagationFlags,$accessControlType)

    #Applies above variable to top-level folder
    $homeDrivesDiracl.SetAccessRule($accessRule)
    Set-Acl -path $homeDrivesDir $homeDrivesDiracl
  

#------------------Background Guff---------------------------#

# 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 ""

#-----------------Reports or Fix Mode------------------------#

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 $homeFolders) {

 # Put 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 -path $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 "permissions correctly applied"
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
 
Last edited:
@warnox why is it not a good idea with home folders?

Even with the fixes above, i'm still having issues. The share permissions are being set correctly, but the users permissions on each of their folders aren't. I'm getting no errors to go off, but even trying to clear all the permissions from each of the folders prior to putting the new permissions on isn't working

This is mighty frustrating I have to say
 
Hi warnox, there isn't a share per user, there is one share, with the user folders within in it.

What I dont want to happen is for everyone:full. Its not secure and it not right in my book.

It should be:

Share
Domain Admins: Full control, Folder, subfolders and files
Domain Users: Read, list and traverse, This folder only

User Folders
Domain Admins: Inherited from share permissions
%username%: Full control, This folder, subfolders and files.

The issue at the moment, is that the permissions are set incorrectly and I want a script to fix it.
 
Hi warnox. I'm not wanting to use Everyone at all. Its ridiculous imo to use this in a domain environment. I'm talking NTFS permissions only here, I used Share as in the share folder as opposed to share permissions.

I'm thinking this is maybe more sensible using a batch file and icacls over powershell
 
Back
Top Bottom