set-acl to AD OU - powershell

I know that this subject was already discussed here but solutions here and on other sites seem not to work for me.
I want to add to CNO: "CLUSTER" permission on OU to Create Computer Object.
More or less all solution are based on following idea:
$ou = 'OU=sql,OU=prod,DC=ssd,DC=xxx,DC=net'
$cno = 'CLUSTER1'
$sid = [System.Security.Principal.SecurityIdentifier](Get-ADComputer -Filter "name -eq `"$cno`"").SID
$acl = get-acl $ou
$objectGUID = New-Object guid bf967a86-0de6-11d0-a285-00aa003049e2
$guidNull = New-Object guid 00000000-0000-0000-0000-000000000000
$ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"ReadProperty,GenericExecute","Allow",$guidNull,"None",$guidNull
$acl.AddAccessRule($ace1)
$ace2 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"CreateChild","Allow",$ObjectGUID,"None",$guidNull
$acl.AddAccessRule($ace2)
set-acl -aclobject $acl $ou
I am getting following error:
Set-Acl : This security ID may not be assigned as the owner of this object
At line:1 char:8
+ set-acl <<<< -aclobject $acl $ou
+ CategoryInfo : NotSpecified: (OU=sql,OU=ssd...=xxx,DC=net:String) [Set-Acl], ADException
+ FullyQualifiedErrorId : ADProvider:SetSecurityDescriptor:ADError,Microsoft.PowerShell.Commands.SetAclCommand
Any idea what can be wrong?

I've seen this error on file systems when using Get-Acl/Set-Acl. Get-Acl retrieves the entire ACL even though you don't want it. You only want the DACL. Set-Acl then attempts to write the entire ACL which fails because Microsoft. Try changing the Get-Acl call to:
$acl = (get-acl $ou).Access
This should only get you the access rules which you are trying to append to.
EDIT
Apologies for the misinformation, on a filesystem this works but AD is "special". The underlying issue is the same, Get-Acl pulls everything and Set-Acl chokes when it attempts to set the owner. Try running the above command in an powershell window run as admin under a domain administrator's context. This may allow you to force past it. Instead I would try using the ADSI accelerator.
$ou = 'OU=sql,OU=prod,DC=ssd,DC=xxx,DC=net'
$cno = 'CLUSTER1'
$sid = [System.Security.Principal.SecurityIdentifier](Get-ADComputer -Filter "name -eq `"$cno`"").SID
$ouObject = [ADSI]("LDAP://$OU")
$objectGUID = New-Object guid bf967a86-0de6-11d0-a285-00aa003049e2
$guidNull = New-Object guid 00000000-0000-0000-0000-000000000000
$ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"ReadProperty,GenericExecute","Allow",$guidNull,"None",$guidNull
$ouObject.psbase.ObjectSecurity.AddAccessRule($ace1)
$ace2 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $sid,"CreateChild","Allow",$ObjectGUID,"None",$guidNull
$ouObject.psbase.ObjectSecurity.AddAccessRule($ace2)
$ouObject.psbase.CommitChanges()
Another option would be to try working around it with dsacls, you'll need to figure out exactly which permissions syntax you want to use though. Please test before running on a live OU.
$ou = 'OU=sql,OU=prod,DC=ssd,DC=xxx,DC=net'
$cno = 'CLUSTER1'
$sid = [System.Security.Principal.SecurityIdentifier](Get-ADComputer -Filter "name -eq `"$cno`"").SID
#should grant the SID Generic Execute, Read Property, Create Children
dsacls $ou /G $sid:GERPCC

seems to be working on any AD object, including DNS records via DN:
dsacls $DistinguishedName /G "NT AUTHORITY\Authenticated Users:GW"

Related

Pass runtime parameters in PowerShell Script

I have a below powerShell script that creates homedrive for user,
Import-Module ActiveDirectory 2>&1 | Write-Host;
if($?)
{
$homeDir = "\\CORP.com\HOME\Jdoe";
$user = "jdoe";
$domain = "Corp";
New-Item "$homeDir" -type directory;
$acl = Get-Acl "$homeDir";
$permission = "$domain\$user","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow";
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission;
$acl.SetAccessRule($accessRule);
$acl | Set-Acl "$homeDir";
}
Values within $homeDir and $User will be passed on runtime basis.
How to execute above script along with pass runtime values in $homeDir and $User attribute.
I have tried to execute,
. 'C:\hd.ps1' $homeDir = "\\CORP.com\HOME\test" $user = "test" ; without success.
Can anyone guide, what i am doing incorrect.
Put
param(
$homeDir,
$user
)
At the top of the script and call using
Powershell -File "C:\hd.ps1" -homeDir "\\CORP.com\HOME\test" -user "test"
Why are you doing this?
Import-Module ActiveDirectory 2>&1 | Write-Host;
If you are on the DC doing this or if you have the RSAT tools on your workstation, if you are on PowerShell v3+ or higher, this gets auto loaded the moment you use an AD cmdlet.
Also never user Write-Host for anything that you plan to need later. It empties / clears the buffer. Write-Host is only good for text coloring or other formatting needs in s
Make this a collection from a file for example and just read it in. I'm just using a list here:
$UserFile = #'
Property,Value
homeDir,\\CORP.com\HOME\Jdoe
user,jdoe
Targetdomain,Corp
'# | ConvertFrom-Csv
# Results
Property Value
-------- -----
homeDir \\CORP.com\HOME\Jdoe
user jdoe
Targetdomain Corp
If you are doing this from a remote machine, then you cannot use local varibles in a remote session unless you set its scope.
Get-Help about_remote_variables -Full
About Remote Variables
LONG DESCRIPTION
You can use variables in commands that you run on remote
computers.Simply assign a value to the variable and then use the
variable inplace of the value.
By default, the variables in remote commands are assumed to be
definedin the session in which the command runs. You can also use
variablesthat are defined in the local session, but you must identify
them aslocal variables in the command.
USING LOCAL VARIABLES
You can also use local variables in remote commands, but you
mustindicate that the variable is defined in the local session.
Beginning in Windows PowerShell 3.0, you can use the Using
scopemodifier to identify a local variable in a remote command.
The semi-colons are not needed in PowerShell, unless the items are on the same line.
You cannot call this code this way...
'C:\hd.ps1' $homeDir = "\\CORP.com\HOME\test" $user = "test"
... since you did not specify any params in your code.
So, something like this...
Note: I am not in a position to test this... please do only in a test environment
So this is off the cuff...
ForEach($UserLine in $UserFile)
{
New-Item $UserLine.homeDir -type directory
$acl = Get-Acl $UserLine.homeDir
$permission = ($Using:UserLine.Targetdomain + '\' + $Using:UserLine.user),'FullControl', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl $Using:UserLine.homeDir
}
If you want this to be a parameterized function, then this.,.
Function New-ADUserHomeDirSettings
{
[cmdletbinding()]
Param
(
[string]$homeDir,
[string]$user,
[string]$Targetdomain
)
$acl = Get-Acl $UserLine.homeDir
$permission = ($Using:UserLine.Targetdomain + '\' + $Using:UserLine.user),'FullControl', 'ContainerInherit, ObjectInherit', 'None', 'Allow'
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl $Using:UserLine.homeDir
}
New-ADUserHomeDirSettings -homeDir '' -user '' -Targetdomain ''

SET-ACL via powershell for computer object

i am trying to modify a permission to multiple computers in my domain so that they are allowed to authenticate cross domain.
My code is simple however i keep getting an error.
Function Add-ADGroupACL
{
param([string]$Computername,[string]$Access)
#Get a reference to the RootDSE of the current domain
$rootdse = Get-ADRootDSE
#Get a reference to the current domain
$domain = Get-ADDomain
#Create a hashtable to store the GUID value of each extended right in the forest
$extendedrightsmap = #{}
Get-ADObject -SearchBase ($rootdse.ConfigurationNamingContext) -LDAPFilter `
"(&(objectclass=controlAccessRight)(rightsguid=*))" -Properties displayName,rightsGuid |
% {$extendedrightsmap[$_.displayName]=[System.GUID]$_.rightsGuid}
#Create a hashtable to store the GUID value of each schema class and attribute
$guidmap = #{}
Get-ADObject -SearchBase ($rootdse.SchemaNamingContext) -LDAPFilter `
"(schemaidguid=*)" -Properties lDAPDisplayName,schemaIDGUID |
% {$guidmap[$_.lDAPDisplayName]=[System.GUID]$_.schemaIDGUID}
#Get the computer object for modification on
$Computer = Get-ADComputer -Identity $Computername
#get the SID of the group you wish to add to the computer.
$GroupIdentity = New-Object System.Security.Principal.SecurityIdentifier(Get-ADGroup -Identity $Access).SID
$computersADPath = "AD:\" + $Computer.DistinguishedName
$ComputerACL = Get-ACL $computersADPath
#Create a new rule to add to the object
$newAccessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
$GroupIdentity,"ExtendedRight",
"Allow",
$extendedrightsmap["Allowed To Authenticate"],
"None")
$newAccessRule
#Add the rule to the ACL
$ComputerACL.AddAccessRule($newAccessRule)
#Set Rules to the ACL
Set-Acl -AclObject $ComputerACL -Path $computersADPath
}
I have posted the entire function to make it easy.
Simply call this as so
Add-ADGroupACL -Computername 'TestComputer' -Access 'TestGroup'
end here is the error message that i keep getting
Set-Acl : This security ID may not be assigned as the owner of this object
At line:88 char:5
+ Set-Acl -AclObject $ComputerACL -Path $computersADPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (CN=testComputer,OU=Co...C=subdomain,DC=domain:String) [Set-Acl], ADException
+ FullyQualifiedErrorId : ADProvider:SetSecurityDescriptor:ADError,Microsoft.PowerShell.Commands.SetAclCommand
The Access Rule looks right. it shows this.
ActiveDirectoryRights : ExtendedRight
InheritanceType : None
ObjectType : 68b1d179-0d15-4d4f-ab71-46152e79a7bc
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : ObjectAceTypePresent
AccessControlType : Allow
IdentityReference : S-1-5-21-2926237862-3770063950-2320700579-361721
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
Any help would be greatly appreciated.
Thank you.
For anyone else who gets this problem, the here is the solution.
Basically, how Get-ACL and Set-ACL works is that it retrieves the entire ACL. you make edits to the ACL and then Set-ACL attempts to rewrite the entire ACL.
More Info: https://learn.microsoft.com/en-us/windows/desktop/secauthz/access-control-entries
So basically you need to just create an ACE and add it to the ACL on the fly. this can best be done buy utilising DACLS
Code:
Function Add-ADGroupACEExtendedRight
{
param(
[string]$Computername = $(throw "Computer name must be specified"),
[string]$Access = $(throw "User or group in which to give acces must be specifieds"),
[string]$ExtendedRight = $(throw "Extended Right Property Name Required")
)
#Get the computer object for modification on
$Computer = Get-ADComputer -Identity $Computername
#get the SID of the group you wish to add to the computer.
$GroupIdentity = New-Object System.Security.Principal.SecurityIdentifier(Get-ADGroup -Identity $Access).SID
#Set Permissions
dsacls $Computer.DistinguishedName /G $GroupIdentity":CA;"$ExtendedRight
}
Usage:
Add-ADGroupACEExtendedRight -Computername "TestAsset" -Access "GroupID" -ExtendedRight "Allowed To Authenticate"
you can add any extended right here.
more information on DACLS: https://technet.microsoft.com/pt-pt/library/cc787520%28v=ws.10%29.aspx?f=255&MSPPError=-2147217396

Change NTFS permissions using Powershell and UNC path [duplicate]

I am running this script as Admin and It does create the folders requred, just does not set the appropriate permissions.
$Users = Get-Content "D:\New_Users.txt"
ForEach ($user in $users)
{
$newPath = Join-Path "F:\Users" -childpath $user
New-Item $newPath -type directory
$UserObj = New-Object System.Security.Principal.NTAccount("DOMAIN",$user)
$acl = Get-Acl $newpath
$acl.SetAccessRuleProtection($True, $False)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("O1OAK\$user","AppendData,CreateDirectories,CreateFiles,DeleteSubdirectoriesAndFiles,ExecuteFile,ListDirectory,Modify,Read,ReadAndExecute,ReadAttributes,ReadData,ReadExtendedAttributes,ReadPermissions,Synchronize,Traverse,Write,WriteAttributes,WriteData,WriteExtendedAttributes","ContainerInherit, ObjectInherit","None","Allow")
$acl.SetAccessRule($accessRule)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NT AUTHORITY\SYSTEM","FullControl","ContainerInherit, ObjectInherit","None","Allow")
$acl.SetAccessRule($accessRule)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators","FullControl","ContainerInherit, ObjectInherit","None","Allow")
$acl.SetAccessRule($accessRule)
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("1OAK\$user","Delete","ContainerInherit, ObjectInherit","None","Allow")
$acl.removeAccessRule($accessRule)
$acl.SetOwner($UserObj)
$acl | Set-Acl $newpath
}
The first error in a string of 3 that I get is below. I think it is the most important and will fix the other 2.
Exception calling "SetAccessRule" with "1" argument(s): "Some or all identity references could not be translated."
At D:\DOMAIN\IT\IT Private\User Drives\user_folders.ps1:12 char:20
+ $acl.SetAccessRule <<<< ($accessRule)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
The error is pretty self explanatory: Some or all identity references could not be translated.
This means the account couldn't be found. So what you have to do is verify your accounts. Since you're adding 4 ACE's, you'll need to identify which is invalid.
The easiest way to do this is to debug through, line by line using the ISE or PowerGUI.
I tried your code with "NT AUTHORITY\SYSTEM" and "BUILTIN\Administrators" and it works so the issue is with "O1OAK\$user" or "1OAK\$user". You likely have an invalid account in your text file.
a gotch with the user ID is that AD truncates the username, so a user with a long name "j_reallylongname" will have a samid (Security Account Manager (SAM) account name) which is truncated. (j_reallylong)
so when fetching usernames, make sure you verify against the AD before using it.
When i've got the upns, so i run a dsget query to get the samid then use that to build the identity reference.
Adding this in case any C#/ASP.NET developers get this (which is my scenario, and I found this post).
I am using .NET Core in a corporate environment, and I need to check UserGroups as part of security. The code is like (where "user" is a ClaimsPrincipal):
var windowsIdentity = user.Identity as WindowsIdentity;
if( windowsIdentity is null )
throw new Exception( $"Invalid Windows Identity {user.Identity.Name}" );
return windowsIdentity.Groups
.Select( g => g.Translate( typeof( NTAccount ) ).Value );
Anyway, someone in charge of groups deleted a group I was part of, and the AD replication lag caused me to get the error in the title. A logoff and/or reboot worked just fine.
For me it was a case of where i verified whether the script execution knew the password by using $user = Get-Credential "username". i had to turn my $user into $user.UserName To give the script parameters the value they were expecting

Single PowerShell Script to Create Folder, AD Groups, and Apply New Groups to Folder

I'm wanting to:
Create New Folder
Set Share Name for folder so that users can see it
Create AD Group FS-TESTSHARE-R
Create AD Group FS-TESTSHARE-RW
Apply Both groups to the new share folder
Set Full Read permissions to FS-TESTSHARE-R
Set Full Read/Rights permissions to FS-TESTSHARE-RW
Set full access permissions to Domain Admins
Here is what I have now after playing around a little bit, but I wanted to make sure I didn't miss anything. I've decided (for the time being to leave out the param settings, but I can come back to that later. Does this look correct or is there a better way to write the script?
I've also ran into a bunch of errors about unexpected
New-ADGroup
-Name "FS-$NAME-RW"
-SamAccountName "FS-"+$NAME+"-RW"
-GroupCategory Security
-GroupScope Global
-DisplayName "$NAME Read-Write Access"
-Path "CN=$LOCATION,CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL"
-Description "Members of this group have read-write access to the test share"
New-ADGroup
-Name "FS-$NAME-R"
-SamAccountName "FS-"+$NAME+"-R"
-GroupCategory Security
-GroupScope Global
-DisplayName "$NAME Read Access"
-Path "CN=$LOCATION,CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL"
-Description "Members of this group have read access to the test share"
# create new folder
New-Item -Path $Path -ItemType Directory
# get permissions
$acl = Get-Acl -Path $Path
#Get Security Groups
get-adobject -searchbase "CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL" -ldapfilter {(objectclass=group)}
# add a new permission
$acl.SetAccessRuleProtection($True, $False)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("Administrators","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("esg.intl\Domain Admins","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("esg.intl\"FS-"+$NAME+"-R"","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("esg.intl\"FS-"+$NAME+"-RW"","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
$acl.AddAccessRule($rule)
# set new permissions
$acl | Set-Acl -Path $path
I'm also running into some errors and I'm not sure I understand how to fix them...
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:44 char:96
+ ... " -ldapfilter {(objectclass=group)}
+ ~
Use `{ instead of { in variable names.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:55 char:82
+ ... ule("esg.intl\"FS-"+$NAME+"-R"","FullControl", "ContainerInherit, ObjectInherit" ...
+ ~~~~~~~~~~~~~~~~
Unexpected token 'FS-"+$NAME+"-R""' in expression or statement.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:55 char:82
+ ... ule("esg.intl\"FS-"+$NAME+"-R"","FullControl", "ContainerInherit, ObjectInherit" ...
+ ~
Missing closing ')' in expression.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:55 char:164
+ ... "None", "Allow")
+ ~
Unexpected token ')' in expression or statement.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:58 char:82
+ ... ule("esg.intl\"FS-"+$NAME+"-RW"","FullControl", "ContainerInherit, ObjectInherit ...
+ ~~~~~~~~~~~~~~~~~
Unexpected token 'FS-"+$NAME+"-RW""' in expression or statement.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:58 char:82
+ ... ule("esg.intl\"FS-"+$NAME+"-RW"","FullControl", "ContainerInherit, ObjectInherit ...
+ ~
Missing closing ')' in expression.
At C:\Users\A-Shane.Johnson\Desktop\ShareFolderCreation.ps1:58 char:165
+ ... "None", "Allow")
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : OpenBraceNeedsToBeBackTickedInVariableName
Ok, so a couple things I see. First, string interpolation... Where you have:
"FS-"+$NAME+"-RW"
You can shorten that to simply:
"FS-$NAME-RW"
When a variable is found within double quotations like that it will try to expand the variable into a string automatically. I am not going to get into stipulations or rules, since I think that would only over-complicate this. Suffice it to say that this change alone, when applied to all instances where it can be in your script, will probably remove most of your errors. ...and possibly create new ones since several commands would then be correctly interpreted.
Next, command syntax. Your first two commands, unless you have escaped the new lines and that is simply not reflected in your question, are likely not going to execute as you would expect them. If you want to space out your parameters like you have I would suggest setting them up as hashtables, and then expanding the hashtable when executing the command. You can do that like this:
$GroupParams= #{
'Name' = "FS-$NAME-RW"
'SamAccountName' = "FS-$NAME-RW"
'GroupCategory' = "Security"
'GroupScope' = "Global"
'DisplayName' = "$NAME Read-Write Access"
'Path' = "CN=$LOCATION,CN=SECURITY GROUPS,CN=FILE SHARE GROUPS,DC=ESG,DC=INTL"
'Description' = "Members of this group have read-write access to the test share"
}
New-ADGroup #GroupParams
Your LDAPFilter line error, well, that line looks superfluous so I'd say comment it out and move on.
Please note that you are giving FullAccess rights to the Read group, you probably want to change that to ReadAndExecute.
Lastly, if you have trouble with your ACLs then I'll give you the same advise I give anybody when dealing with ACLs on file shares. Define your settings explicitly, then apply them as an access rule. I use the following as a template:
$Rights = [System.Security.AccessControl.FileSystemRights]"FullControl"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ObjectInherit,ContainerInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount("IIS_IUSRS")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($objUser, $Rights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL "C:\Temp"
$objACL.AddAccessRule($objACE)
Set-ACL "C:\Temp" $objACL
On a side note, you never really deal with the whole network share thing of declaring a share name and what not. You may want to run get-help New-SMBShare -Full to get more info on setting up the network share.

Why does Set-Acl on the drive root try to set ownership of the "object"?

I would like to change the ACL of the C: drive. What im trying to do is remove the permission that a user can create a folder directly on the drive. I tested the script on another folder while writing it. It worked without a problem. After completion i tried the script in our test envoirnment on the actual drive. I get an error that i cant figure out. If i remove the permission manualy it works without a problem. Anyone got an idea?
$path = "C:\"
$colRights = [System.Security.AccessControl.FileSystemRights]"CreateDirectories"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount("Authenticated Users")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL $path
$objACL.RemoveAccessRule($objACE)
Set-ACL $path $objACL
The error is:
Set-Acl : The security identifier is not allowed to be the owner of this object.
At C:\Users\mhodler\Desktop\Remove Permission.ps1:57 char:8
+ Set-ACL <<<< $path $objACL
+ CategoryInfo : InvalidOperation: (C:\:String) [Set-Acl], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.SetAclCommand
I found the answer. Microsoft says
Unfortunately Get-Acl is missing some features. It always reads the full security descriptor even if you just want to modify the DACL. That’s why Set-ACL also wants to write the owner even if you have not changed it. Using the GetAccessControl method allows you to specify what part of the security descriptor you want to read.
Replace the Get-Acl call with
$acl = (Get-Item $path).GetAccessControl('Access')
You need the SeRestorePrivilege to set the owner. I used Lee Holmes' script from the URL below to elevate my process with this additional priv and was able to set the owner to someone other than myself.
http://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/
I tried the (get-item $path).getaccesscontrol("access") method but still got the same error since my process didn't have the SeRestorePrivilege.
The below code works for me:
$ApplicationPoolIdentity = "everyone"
function SetACL()
{
param (
[Parameter(Mandatory=$true)]
[string] $Path
)
$Acl = (Get-Item $Path).GetAccessControl('Access')
Write-Host "Path:" $Path "ID:" $ApplicationPoolIdentity
$Ar = New-Object system.security.accesscontrol.filesystemaccessrule($ApplicationPoolIdentity,"Write","Allow")
$Acl.SetAccessRule($Ar)
Write-Host $Acl
$Acl | Set-Acl $Path
}
SetACL "C:\Test\"
People may find this easier:
icacls c:\ /remove "authenticated users"
$Acl = (Get-Item $Path).GetAccessControl('Access')
Worked for me.
I run my PS Script from CMD and in this PS Script i run another PS Script everything works fine as long as i do it with my own User. When i use different User i get the same Error:
Set-Acl : The security identifier is not allowed to be the owner of this object.
Just changed Get-ACL to that Line above and it worked fine.
Thanks again.