PowerShell: Set-Acl Does Not Appear to Work

If you’ve ever dealt with NTFS permissions in VBScript, you will no doubt appreciate just how easy PowerShell now makes it to manage access control lists. Basic examples in PowerShell books and around the ‘net look something like this:

$directory = "Test"
$acl = Get-Acl $directory
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("IUSR_CRACKLIN", "Modify", "Allow")
$acl.AddAccessRule($accessrule)
set-acl -aclobject $acl $directory

In the example above, user “IUSR_CRACKLIN” is given Modify access to the Test directory. Running the code above will not produce any errors but upon checking permission via the GUI, it seems as though the user was added, but no permissions were set.

I thought that perhaps this was an issue with Vista and I tried it on Windows Server 2003. And that’s when I noticed that the directory had been given “Special Permissions.” When I checked the Advanced permissions, I could see that Modify access had been assigned, but only to “This Folder.” Other folders that had the checkboxes checked listed “This Folder, subfolders and files”

Since I wanted the Test directory permissions to match the others, I searched the Google to see which flags would give me “This Folder, subfolders and files.” I found Damir Dobric’s blog post titled “Directory Security and Access Rules which sported a handy reference table flags that must be set to achieve various scenarios.

Subfolders and Files only InheritanceFlags.ContainerInherit, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly
This Folder, Subfolders and Files    InheritanceFlags.ContainerInherit, InheritanceFlags.ObjectInherit, PropagationFlags.None
This Folder, Subfolders and Files InheritanceFlags.ContainerInherit, InheritanceFlags.ObjectInherit, PropagationFlags.NoPropagateInherit
This folder and subfolders InheritanceFlags.ContainerInherit, PropagationFlags.None
Subfolders only InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly
This folder and files InheritanceFlags.ObjectInherit, PropagationFlags.None
This folder and files InheritanceFlags.ObjectInherit, PropagationFlags.NoPropagateInherit

So it setting the following should give me what I need:
InheritanceFlags.ContainerInherit, InheritanceFlags.ObjectInherit and PropagationFlags.None
.

$directory = "Test"
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
$acl = Get-Acl $directory
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("IUSR_CRACKLIN", "Modify", $inherit, $propagation, "Allow")
$acl.AddAccessRule($accessrule)
set-acl -aclobject $acl $directory

I then checked the permissions and voila:

Imagine that.. PowerShell can set any number of permissions with about 6 lines of code while VBScript requires over 36 lines JUST to set the constants needed for managing permissions. I’m so excited thinking about the possibilities: PowerShell + Windows Core + SSH is going to be awesome.

Chrissy is a Cloud and Datacenter Management & Data Platform MVP who has worked in IT for over 20 years. She is the creator of the popular SQL PowerShell module dbatools, holds a master's degree in Systems Engineering and is coauthor of Learn dbatools in a Month of Lunches. Chrissy is certified in SQL Server, Linux, SharePoint and network security. You can follow her on Twitter at @cl.

Posted in PowerShell, Security