Powershell Set-Acl use without changing owner?
I have a folder, and I am trying to grant full permissions to another user, like so:

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

November 26th, 2009 2:28pm

Does the SyncProcess account have the "changepermisson" right on the folder?
Free Windows Admin Tool Kit Click here and download it now
November 26th, 2009 2:59pm

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 utility or WMI.
November 26th, 2009 2:59pm

Thanks for your responses.

Vadims, this seems pretty restrictive and I haven't seen it clearly documented anywhere. Is this by design?


Free Windows Admin Tool Kit Click here and download it now
November 26th, 2009 3:05pm

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:

"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?
November 26th, 2009 4:33pm

> Vadims, this seems pretty restrictive and I haven't seen it clearly documented anywhere. Is this by design?

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).
Free Windows Admin Tool Kit Click here and download it now
November 26th, 2009 4:37pm

If your service account can take ownership you could script the change of ownership prior to setting the ACL:
$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"
}

November 26th, 2009 5:34pm

and how you restore ownership back to original? SetOwner() wouldn't work..

Free Windows Admin Tool Kit Click here and download it now
November 26th, 2009 5:42pm

I didn't say you could set it back :) ...Just that it's a way that you could set the acl's using your service account.
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.
November 26th, 2009 5:50pm

> Just that it's a way that you could set the acl's using your service account

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.
Free Windows Admin Tool Kit Click here and download it now
November 26th, 2009 5:54pm

Good discussion. In my case, I solved the problem by ensuring that the script user is the owner of these folders. If another user tries to run them manually, it will probably barf and confuse the ____ out of them... which I think is a big downside to powershell capability. However, this is for an automated build script, so manual running should be rare.

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.

November 26th, 2009 9:39pm

instead of write-output use write-host cmdlet. Or just:
"The path is: $myPath" + "\Subfolder"
Free Windows Admin Tool Kit Click here and download it now
November 26th, 2009 10:13pm

You can change the owner back to the former account after setting the right, but you need the restore permission for that.
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
November 27th, 2009 10:58pm

Using PSCX extensions you can do this:
$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
Free Windows Admin Tool Kit Click here and download it now
November 28th, 2009 7:45am

Vadims,
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?
November 30th, 2009 12:28am

You need to ask in PSCX home page.
http://www.codeplex.com/PowerShellCX

Free Windows Admin Tool Kit Click here and download it now
November 30th, 2009 10:23am

Hello

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.
March 10th, 2010 10:37pm

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
Free Windows Admin Tool Kit Click here and download it now
April 6th, 2011 9:40pm

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.

April 27th, 2011 10:13am

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 :)

  • Proposed as answer by Qbic808 Friday, December 16, 2011 11:47 AM
  • Unproposed as answer by Qbic808 Friday, December 16, 2011 11:47 AM
Free Windows Admin Tool Kit Click here and download it now
April 27th, 2011 1:00pm

I found this article worked around the issue of having to change ownership in order to set ACL's.

May be of use:

http://www.bilalaslam.com/2010/12/14/powershell-workaround-for-the-security-identifier-is-not-allowed-to-be-the-owner-of-this-object-with-set-acl/

 

  • Proposed as answer by Jake Schmidt Friday, February 22, 2013 5:58 PM
December 16th, 2011 11:48am

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/

Free Windows Admin Tool Kit Click here and download it now
April 10th, 2012 5:01pm

I know this is an old thread but the link posted by Qbic808 is what fixed this for me.
February 22nd, 2013 5:59pm

write-output "The path is: $($myPath)\Subfolder"
Free Windows Admin Tool Kit Click here and download it now
February 5th, 2014 8:44pm

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.

February 26th, 2014 7:17pm

Using the Set-SecurityDescriptor function from this module will also work (you'd have to use Get-SecurityDescriptor first to get the SD instead of the .GetAccessControl method). As an admin, you can also change the owner of the SD if you'd like (using either Set-Owner or Set-SecurityDescriptor).
Free Windows Admin Tool Kit Click here and download it now
February 26th, 2014 7:32pm

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
March 18th, 2014 10:12am

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! 

Free Windows Admin Tool Kit Click here and download it now
July 22nd, 2015 11:43am

This topic has been closed for years (6 years).  Please open a new topic with your new issue. 

July 22nd, 2015 12:04pm

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics