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 $directoryIn 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 $directoryI 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.



July 28th, 2007 - 07:45
How to utilize Directory Security and Access Rules in .NET?http://developers.de/blogs/damir_dobric/archive/2007/06/18/directory-security-and-access-rules.aspx#1457
August 27th, 2007 - 20:36
Thank you
I’m writing a ps script about batch creating floders with certain ACL.
September 25th, 2007 - 03:30
Thanks for the post! That saved a whole bunch of time (and like your experience, cut down my VBScript)
January 25th, 2008 - 13:24
Another option use xcacls or cacls… You can do this at the command line of your shell and pass it parameters in 1 line of code. This is what I have done in the past with automating our file server, works, it’s slow but it works.
January 15th, 2009 - 06:13
Hello,
I am using BlogEngin.NET open source application. Afer transfering to New Hosting Provider. I getting error of access denied. Which is basically the problem of permission of “App_Data” Folder.
I told to my hosting provider. They told me that we have set the permission. After that I will getting this error ocasionally means some times. I will refersh the page again and again then sudenly error comes. If you go through all page one by one then suddenly error appears.
If you want to check my website is http://elevatesoftsolutions.in/default.aspx
Please let me any other way to set the permission to existing folder.
Thanks
Kunal Mehta
–
http://360by2.blogspot.com/
January 8th, 2010 - 13:04
Hey Thanks for that! I’ve been using a script in Powershell that sets up all my users for me daily in including home folder and permissions. the only stumbling block was I had to keep going in and resetting the subfolder permissions after.
THIS NAILED IT!
Sean
the Energized Tech
January 25th, 2010 - 12:07
Thanks for the post. I’m trying to use Powershell to tell me (amongst other things) if an ACE within an ACL was set explicitly or inherited. In GUI terms this means: are the tickboxes for the relevant ACE enabled or greyed out?
I thought that info would be stored in PropagationFlags or InheritanceFlags, but sadly my two test folders report identical settings for those despite one have explicit perms set and the other being inherited.
Any insights?!
January 25th, 2010 - 12:11
UPDATE: As is always the case, I found the answer immediately after posting! There is another property of the ACE called “IsInherited” which evaluates to either true or false and is exactly what I was after!
March 5th, 2010 - 04:09
Really useful post – save me loads of time
March 5th, 2010 - 09:44
Any get this error intermitently when running the New-Object part of the script above?
“New-Object : Cannot find an overload for “FileSystemAccessRule” and the argument count: “5″.”
I can’t pin down what is changing when I do and don’t get this.
March 15th, 2010 - 11:00
I eventually “solved this” myself, but I don’t understand how/why it works:
If you do :
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule($UserObject, “Modify”, “3″, “None”, “Allow”)
ie pass the arguments direct, it works. There is probably something obvious going on here, but I don’t have time to work out what at the moment.
July 13th, 2010 - 13:00
Great post!
Another way to pass the arguments directly:
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule(“IUSR_CRACKLIN”, “Modify”, “ContainerInherit,ObjectInherit”, “None”, “Allow”)
January 17th, 2011 - 06:35
I got: The security identifier is not allowed to be the owner of this object
Resolution: http://www.bilalaslam.com/powershell-workaround-for-the-security-identifier-is-not-allowed-to-be-the-owner-of-this-object-with-set-acl/
June 19th, 2011 - 05:48
… and it could be done in ONE line at the "shell" command prompt, on VMS forty years ago. (The whole concept, most of the syntax, and the interactions among, ownership, protections, and ACLs, was lifted almost in one piece from VMS by the Windows NT system architect, Dave Cutler. Then Microsoft mixed in its own peculiar brand of f'd-uppedness, and now we have the PowerShell way of doing it. Yay.)
June 29th, 2011 - 06:38
If you want "files only" use InheritanceFlags.ObjectInherit and PropagationFlags.InheritOnly
August 30th, 2011 - 08:09
Great post! It finaly helped me a lot, finishing my script! Thanks!
May 13th, 2013 - 15:51
Just what i needed!
August 18th, 2011 - 13:40
Same thing for me!
Thanks!!