The PowerShell script discussed in this post allows you to create a new folder, remove the inherited permissions, and set new permissions for a new Active Directory group.
Latest posts by Robert Pearman (see all)

Creating a new folder is an easy task to accomplish: either right-click in the parent folder or use the “New Folder” button in the Explorer ribbon.

This is all well and good, but this folder then inherits the permissions of the parent folder. On your desktop or in your documents folder, this is perfectly fine. However, what if you are creating this folder in a network share? What if the folder requires specific permissions?

I once managed an environment in which a parent folder required specific permissions when a new “contract” was brought on board. It also needed to have six sub-folders, all with unique permissions, with groups named for the contract as well as for role-based groups across the organization.

This process was labor intensive, required extensive documentation, and was prone to human error.

I managed to automate the process of creating the folder structure, groups, and permissions so that—instead of it taking someone 45 minutes and getting it wrong—it took 10 seconds and was perfect every time.

In the following example, we will demonstrate adding a new folder to an existing shared folder, removing inherited permissions, creating two new AD Groups, and setting the Access Control List.

First we need to import the ActiveDirectory Module and define the parent folder path. The parent folder can be either a local folder or one defined via a UNC path.

Import-Module ActiveDirectory
 $path = "\\server12r2\Shared\"
 $newFolderName = Read-Host -Prompt "Enter Name of New Folder"
 $newFolderFull = $path + $newFolderName
 Write-Output "New Folder will be: $newFolderFull"
 $confirm = Read-Host "Confirm? Y/N"
 If(($confirm) -ne "y")
 {
     # End
 }
 Else
 {}

At this point, we have created a simple PowerShell script to define the name of our new folder and confirm what we have entered.

Folder created

Folder created

Assuming that we have confirmed the folder name (“Y”), we can create the folder and groups.

In organizations I manage, I like to name the AD Groups based on the NTFS Path. For example, a group giving access to finance in the “shared” share would be named “Shared.Finance,” then appended with an “R” for read only or “RW” for read/write (modify). I wish I could claim that as my idea, but it came from another engineer with whom I worked. I have employed it everywhere else I have worked.

We can flesh out our PowerShell code with comments and or with “Output” commands. I like to use Output even if the resulting script will be run by a scheduler. If it is ever run interactively, it gives you a good progress indicator. I also have an OU just for storing these groups, so you can also add that into the New-ADGroup command, if you wish.

Inside our “Else” block, we can add the following:

Write-Output "Create AD Groups"
$groupnameRW = "Shared.$newFolderName.RW"
$groupnameR = "Shared.$newFolderName.R"
New-AdGroup $groupNameRW -samAccountName $groupNameRW -GroupScope DomainLocal -path "OU=NTFS Groups,DC=TR12R,DC=local"
New-AdGroup $groupNameR -samAccountName $groupNameR -GroupScope DomainLocal -path "OU=NTFS Groups,DC=TR12R,DC=local"

Next we can add the folder itself and remove inherited permissions:

Write-Output "Add Folder.."
New-Item $newFolderFull -ItemType Directory
Write-Output "Remove Inheritance.."
icacls $newFolderFull /inheritance:d

If we run our code now, a new folder will be created, and inherited permissions will be converted into explicit permissions for the folder. The two AD groups will also be created. You will need to ensure that you are using an elevated PowerShell session to create the groups.

As you can see from the ACL, inheritance has been removed.

Setting folder permissions

Setting folder permissions

In the next section, we will create some new ACL rules and remove some entries from the ACL.

This TechNet page is a very useful resource for information regarding security descriptors.

An ACL rule is split into five arguments:

  • Rights
  • Inheritance
  • Propagation
  • User
  • Type

Rights allow you to control the type of access to a resource. Most commonly it will be set to “ReadAndExecute” or “Modify,” but there is a full list of access types available, matching anything you can set in the GUI.

Inheritance can be set to apply only to a folder or to all sub-folders and files. Propagation works similarly.

User is the security principal for whom we are creating the rule; it could be a group or a user.

Type is set to allow or deny access.

These five items should be defined like this:

# Rights
$readOnly = [System.Security.AccessControl.FileSystemRights]"ReadAndExecute"
$readWrite = [System.Security.AccessControl.FileSystemRights]"Modify"
# Inheritance
$inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
# Propagation
$propagationFlag = [System.Security.AccessControl.PropagationFlags]::None
# User
$userRW = New-Object System.Security.Principal.NTAccount($groupNameRW)
$userR = New-Object System.Security.Principal.NTAccount($groupNameR)
# Type
$type = [System.Security.AccessControl.AccessControlType]::Allow

Using these seven examples, we can build an ACL rule entry:

$accessControlEntryRW = New-Object System.Security.AccessControl.FileSystemAccessRule @($userRW, $readWrite, $inheritanceFlag, $propagationFlag, $type)

It is also then easy to add additional rules by varying the rule entries:

$accessControlEntryR = New-Object System.Security.AccessControl.FileSystemAccessRule @($userR, $readOnly, $inheritanceFlag, $propagationFlag, $type)

To actually enter these rules into the ACL, we first need to collect the current ACL of the folder, using Get-ACL:

$objACL = Get-ACL $newfolderFull

Then we can add a rule:

$objACL.AddAccessRule($accessControlEntryRW)

To save that change, we use “Set-ACL,” defining the path to the folder and the ACL to apply:

Set-ACL $newFolderFull $objACL

Earlier I mentioned removing unwanted permissions. To do that, we need to create an ACL rule entry for the group or user we want to remove:

$accessControlEntryDefault = New-Object System.Security.AccessControl.FileSystemAccessRule @("Domain Users", $readOnly, $inheritanceFlag, $propagationFlag, $type)

Then, using the same procedure above, we remove all entries for that security descriptor:

$objACL = Get-ACL $newFolderFull
 $objACL.RemoveAccessRuleAll($accessControlEntryDefault)

I have to remove the domain users from my test folder and replace them with my group-based permissions:

$accessControlEntryDefault = New-Object System.Security.AccessControl.FileSystemAccessRule @("Domain Users", $readOnly, $inheritanceFlag, $propagationFlag, $type)
$accessControlEntryRW = New-Object System.Security.AccessControl.FileSystemAccessRule @($userRW, $readWrite, $inheritanceFlag, $propagationFlag, $type)
$accessControlEntryR = New-Object System.Security.AccessControl.FileSystemAccessRule @($userR, $readOnly, $inheritanceFlag, $propagationFlag, $type)
$objACL = Get-ACL $newFolderFull
$objACL.RemoveAccessRuleAll($accessControlEntryDefault)
$objACL.AddAccessRule($accessControlEntryRW)
$objACL.AddAccessRule($accessControlEntryR)
Set-ACL $newFolderFull $objACL

I measured the start and stop time of the code to time the process. It took 6 seconds to execute, which includes the time it took me to type the folder name and confirm it.

This is a very basic example of how you can create and secure a folder using PowerShell. As I explained in the introduction, I was able to use this method to consistently and quickly create many nested folders, all with different security settings.

This is the entire script:

Subscribe to 4sysops newsletter!

Import-Module ActiveDirectory
$path = "\\server12r2\Shared\"
$newFolderName = Read-Host -Prompt "Enter Name of New Folder"
$newFolderFull = $path + $newFolderName
Write-Output "New Folder will be: $newFolderFull"
$confirm = Read-Host "Confirm? Y/N"
If(($confirm) -ne "y")
{
 # End
}
Else
{
Write-Output "Create AD Groups"
$groupnameRW = "Shared.$newFolderName.RW"
$groupnameR = "Shared.$newFolderName.R"
New-AdGroup $groupNameRW -samAccountName $groupNameRW -GroupScope DomainLocal -path "OU=NTFS Groups,DC=TR12R,DC=local"
New-AdGroup $groupNameR -samAccountName $groupNameR -GroupScope DomainLocal -path "OU=NTFS Groups,DC=TR12R,DC=local"
Write-Output "Add Folder.."
New-Item $newFolderFull -ItemType Directory
Write-Output "Remove Inheritance.."
icacls $newFolderFull /inheritance:d
# Rights
$readOnly = [System.Security.AccessControl.FileSystemRights]"ReadAndExecute"
$readWrite = [System.Security.AccessControl.FileSystemRights]"Modify"
# Inheritance
$inheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
# Propagation
$propagationFlag = [System.Security.AccessControl.PropagationFlags]::None
# User
$userRW = New-Object System.Security.Principal.NTAccount($groupNameRW)
$userR = New-Object System.Security.Principal.NTAccount($groupNameR)
# Type
$type = [System.Security.AccessControl.AccessControlType]::Allow
$accessControlEntryDefault = New-Object System.Security.AccessControl.FileSystemAccessRule @("Domain Users", $readOnly, $inheritanceFlag, $propagationFlag, $type)
$accessControlEntryRW = New-Object System.Security.AccessControl.FileSystemAccessRule @($userRW, $readWrite, $inheritanceFlag, $propagationFlag, $type)
$accessControlEntryR = New-Object System.Security.AccessControl.FileSystemAccessRule @($userR, $readOnly, $inheritanceFlag, $propagationFlag, $type)
$objACL = Get-ACL $newFolderFull
$objACL.RemoveAccessRuleAll($accessControlEntryDefault)
$objACL.AddAccessRule($accessControlEntryRW)
$objACL.AddAccessRule($accessControlEntryR)
Set-ACL $newFolderFull $objACL
}
avataravataravatar
38 Comments
  1. Michael Maertzdorf 3 years ago

    Rather informative,

    Now I have this issue

    I have a list of users 1x 40-ish and 1x 180-ish, list is in a CSV

    I'm using the following script to create folders based on "name" (entry in CSV)

    
    Set-Location "c:\data\groups" 
     
    $Folders = Import-Csv c:\scripts\GroupdOnTRG.csv 
     
    ForEach ($Folder in $Folders) { 
     
    New-Item $Folder.Name -type directory 
    }

    This will create the folder in "c:\data\groups" 

    However, I need to set individual user access rights on each folder (folder-name = username)

    Any suggestions?

  2. Jorge 2 years ago

    Hi,

    Very useful for my organization.

    I had to put a 

    Start-Sleep -s 15

    after the group creation to wait for the group to be available for permissions assignments.

    Thank you.

  3. Greg Droid 2 years ago

    This is incredibly helpful and useful, so easy to use.  A true time saver.  One modification I am trying to make is, I would like for the resulting NTFS permissions to not have the local server Users group included. Specifically, "Users (SERVERNAME\Users)"  

    Does anyone know how I could achieve this?  

    Thanks

    avatar
    • Leos Marek 2 years ago

      Greg, I will look into that later today or tomorrow and ping you the script.

Leave a reply

Your email address will not be published.

*

© 4sysops 2006 - 2022

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account