$Acl = Get-Acl "C:\MyFolder"
$AccessRule = New-Object system.security.accesscontrol.filesystemaccessrule("bobby","FullControl", "Allow")
$Acl.AddAccessRule($AccessRule)
Set-Acl -AclObject $Acl "C:\MyFolder"
The owner of the folder is "Joe".
The powershell script runs under the "SyncProcess" account.
If Joe is the owner of the folder, the script fails with the error message:
Set-Acl : The security identifier is not allowed to be the owner of this object
If I change the owner of the folder manually to SyncProcess, then the script runs fine without error.
My question is, why does Set-Acl try to change the owner? I am not trying to change the owner, nor do I want to. I read the script to mean, get the current Acl, add the full control permission access rule for Bobby, and then update the folder. I don't think I am doing anything here to change the owner?
if I add $Acl | fl both before and after the AddAccessRule method call, the Owner is the same in both, unchanged. Whe does Set-Acl think the owner is changing?
Thanks.
Vadims, this seems pretty restrictive and I haven't seen it clearly documented anywhere. Is this by design?
"No Flags can be set" on the AddAccessRule method call.
However, the same thing works for a folder.
Do files and folders need to be handled differently?
yes this is by design.
> Another related question - if I run the above script for a file, instead of a folder, and define inheritanceFlags ("ContainerInherit, ObjectInherit") with the fileSystemAccessRule, then it fails with the message
you cannot set ineritance flags for files, because there is no objects to which this inheritance can beapplied. Inheritance flags can be set for containers only, because containers (folders) can contain child objects (subfolders, files). File is not container and permissions can be set for this object only (by default).
$Account = new-object system.security.principal.ntaccount("SyncProcess") try { $sid = $Account.translate([system.security.principal.securityidentifier]) } catch { echo "Not a valid user" } if ($sid -ne $null) { $acl = get-owner "c:\MyFolder" $acl.setowner($account) set-acl -aclobject $acl "c:\MyFolder" }
and how you restore ownership back to original? SetOwner() wouldn't work..
Although, this does make me think.... Aren't the rules that you can set ownership to yourself or administrators group? In theory if the service account has take ownershipprivilegesto the file system it could take ownership, change the acl, and then change ownership to administrators. This would probably be a better way of doing it.
and you can got serious problems if file/folder owner access is based on CreatorOwner permissions and/or quotas are enabled. I don't recomend to change file/folder owner if this is notrequired to make another user as owner.
I'm tripping on something else that should be so easy.
$myPath = "C:\Testing"
write-output "The path is: $myPath" #works ok
but how can I get output like this:
The path is: C:\Testing\Subfolder\
write-output "The path is: $myPath\Subfolder" #does not work obviously
write-output "The path is: $myPath" + "\Subfolder" #gives me
The path is: C:\Testing
\Subfolder
How do I concatenate hardcoded strings with variables without spaces or blank lines between them? I tried [string]::Join but even having problems finding docs for that.
"The path is: $myPath" + "\Subfolder"
if you have the PowerShell Community extensions installed, there are Cmdlets in there that you can use to give the Powershell session the needed rights.
once you have those right the setowner should succeed and you can change it back with the SetOwner method.
I had sample scripts but lost them,as I probaly don't have time overthe weekend, I post this anyway as it might get you going
If not I will try to update the tread or make a blogpost about it next week.
B.T.W Oisin did once make cmdlets for me for that purpose, might be that he still has them.
Greetings MOW
- Marked as answer by Mervyn ZhangModerator Monday, November 30, 2009 9:02 AM
$ACL = Get-Acl C:\folder
Set-Privilege (new-object Pscx.Interop.TokenPrivilege "SeRestorePrivilege", $true)
$ACL.SetOwner((new-object System.Security.Principal.NTAccount("FormerUser")))
$ACL | Set-Acl C:\folder
I installed the PSCX extensions. I'm trying to understand how Set-Privelege works. I've been scouring the codeplex site and the files/scripts in the installation folder with no luck finding the code behind this cmdlet. I'm just curious what method it is using to do this. Does the cmdlet use .Net or is it using WMI?
You need to ask in PSCX home page.
http://www.codeplex.com/PowerShellCX
This seems to me a strange "design" goal. The commandlet is called Set-ACL but it sets the whole security descriptor.
You need use a highly privileged account in order to run the commandlet.
If for instance, a service desk member should be able to create folders within a share, he not only needs delegated rights to create a folder and set appropriate permissions, he also needs 'SeTakeOwnershipPrivilege' or 'SeRestorePrivilege'. Both cannot be granted via NTFS permissions, they are privileges which allow effectively to get any data you want and then remove your traces by changing the owner again.
As already described, using Icacls is a workaround, but this requires an external command.
There is an entry on Connect stating this would be a bug:
https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=418906&SiteID=99
Shouldn't the commandlet be enhanced with something like: -setDACL -setSACL -setOwner?
Are there any .Net classes to manipulate the SD without loading it into memory via Get-ACL?
Thank you for your feedback.
unfrtunately you cannot change file/folder permissions using Set-ACL if you are not an owner of this file/folder. You need use icacls.exe utili
I find myself agreeing with Mike here.
I'm trying to use Powershell for as many functions as possible, but not being able to set permissions using a function called 'Set-Acl' makes no sense to me.
I'd disagree, just because they didnt wrap every possible situation in to a spiffy little cmdlet doesnt mean its a lame restriction... it might be lame that they didnt think of that, but, the cool part is there is ALWAYS a way around it with powershell.... I have never worked with a scripting language so powerful that I could do ANYTHING I wanted... sure, not all of its as simple as running a built in cmdlet... but that would be a LOT of work, and we wouldnt have powershell yet... so I'll take it as is and look to the community to build small functions that simplify the things the powershell team wasnt able to wrap in to their cmdlet set.
come complain to me when you find something that just cant be done :)
I found this article worked around the issue of having to change ownership in order to set ACL's.
May be of use:
- Proposed as answer by Jake Schmidt Friday, February 22, 2013 5:58 PM
There is a way to do this without using the PSCX extensions. Lee Holmes has a great script that will accomplish the same goal. Although its a bit lengthy as compared to the "Set-Privilege" command, I prefer it since I can't have the pscx extension on all the desired destinations.
http://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/
The link from Qbic808 doesn't go anywhere useful anymore. The new hotness answer is from here.
E.g. You have a file that has the ACL you want ("source.txt") and you want to set those permissions on a bunch of other files ("*.csv"). Just run this (elevated PowerShell, of course):
(Get-Item source.txt).GetAccessControl('Access') | Set-Acl *.csv
It won't try to change the ownership of the file.
Old thread I know however this problem has been troubling me for some time and comes up now and again. I was determined to solve it and I now believe I have done so. This workaround uses .NET static methods of the underlying [System.IO.File] and [System.IO.Directory] classes respectively.
Function Set-FilePathPermission() { [CmdletBinding(PositionalBinding=$false)] Param( [Parameter(Mandatory=$True)][string][ValidateNotNullOrEmpty()][ValidateScript({Test-Path $_})] $Path, [Parameter(Mandatory=$True)][string][ValidateNotNullOrEmpty()] $Identity, [Parameter(Mandatory=$True)][System.Security.AccessControl.FileSystemRights] $Permission, [Parameter(Mandatory=$false)][string][ValidateSet("Allow","Deny")] $Action = "Allow", [Switch] $DisablePropagation ) #Show all permissions that can be assigned [Enum]::GetNames([System.Security.AccessControl.FileSystemRights]) Write-Host "Setting ""$Action"" ""$Permission"" permissions for identity ""$Identity"" to ""$Path""" -ForegroundColor Cyan $item = Get-Item -Path $Path #If the path that we are setting permission to is a folder then consider inheriatance and propagation if ($item -is [System.IO.DirectoryInfo]) { $inherit = [System.Security.AccessControl.InheritanceFlags] "ContainerInherit, ObjectInherit" if ($DisablePropagation) { $propagation = [System.Security.AccessControl.PropagationFlags] "NoPropagateInherit" } else { $propagation = [System.Security.AccessControl.PropagationFlags] "None" } $acl = [System.IO.Directory]::GetAccessControl($Path) $permissionRule = $Identity, $Permission, $inherit, $propagation, $Action $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permissionRule $acl.AddAccessRule($accessRule) [System.IO.Directory]::SetAccessControl($Path,$acl) } elseif ($item -is [System.IO.FileInfo]) { $acl = [System.IO.File]::GetAccessControl($Path) $permissionRule = $Identity, $Permission, $Action $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permissionRule $acl.AddAccessRule($accessRule) [System.IO.File]::SetAccessControl($Path, $acl) } else { Throw "Unknown file type for path ""$Path""" } }
- Proposed as answer by reidca Wednesday, March 19, 2014 8:17 AM
This function "Set-FilePathPermission" is fantastic! However, if inheritance is broken in a sub folder then this function stops and won't go any further. Is there anything that can be added to enable inheritance and continue adding in permissions? I'm relatively new to Powershell and have tried searching around trying to find this answer myself but all the examples I've come across assumes that proper permission is already in place in order to enable inheritance.
I'm using this particular function for my users profiles stored on a file server. I want to make sure BUILTIN\Administrators is part of every folder and file object.
Thank you!
This topic has been closed for years (6 years). Please open a new topic with your new issue.