I was trying to find a way to set "Apply policy" to "Deny" for a certain group in several GPOs (about 50), so I was looking for a way to do it automatically, when I came across this post at an (aparently) abandoned blog with the following script:
$strGroup = "my group"
$strGPO = "my GPO"
$GroupObject = Get-ADGroup $strGroup
$GroupSid = new-object System.Security.Principal.SecurityIdentifier $GroupObject.SID
$GPOObject = Get-GPO $strGPO
$GPOPath = $GPOObject.path
$GPOADObject = [ADSI]"LDAP://$GPOPath"
$GPOObjSec = $GPOADObject.psbase.ObjectSecurity
$GPOACLList = $GPOObjSec.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier])
$extRight = [system.guid]"edacfd8f-ffb3-11d1-b41d-00a0c968f939"
$ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $GroupSid,"ReadProperty, GenericExecute","Deny","None"
$ace2 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $GroupSid,"ExtendedRight","Deny",$extRight,"All"
$GPOADObject.psbase.get_objectSecurity().AddAccessRule($ace1)
$GPOADObject.psbase.get_objectSecurity().AddAccessRule($ace2)
$GPOADObject.psbase.CommitChanges()
$GPOGPTstr = "\\"+$GPOObject.DomainName+"\SYSVOL\"+$GPOObject.DomainName+"\Policies\{"+$GPOObject.Id+"}"
$acl = Get-ACL $GPOGPTstr
$acl.SetAccessRuleProtection($True, $False)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($strGroup,"ReadAndExecute", "ContainerInherit, ObjectInherit", "None", "Deny")
$acl.AddAccessRule($rule)
Set-Acl $GPOGPTstr $acl
I've added it a foreach
loop, to get my groups from a text file. It works, except for line 14:
$ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $GroupSid,"ReadProperty, GenericExecute","Deny","None"
That throws the following error:
new-object : Multiple ambiguous overloads found for "ActiveDirectoryAccessRule" and the argument count: "4".
At .\denyApplyGPOtoGroup.ps1:16 char:10
+ $ace1 = new-object System.DirectoryServices.ActiveDirectoryAccessRule $GroupSid ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
Of course, line 16 fails, as $ace1
is $null
. Nevertheless, the script kind of works: basically, permissions are applied correctly to the GPC, but not to the GPT, which makes sense with the code and the error thrown. So when I went to the GPMC, clicked on the GPO, and I got a message saying:
“The permissions for this GPO in the SYSVOL folder are inconsistent with those in Active Directory. It is recommended that these permissions be consistent. To change the permissions in SYSVOL to those in Active Directory, click OK.”
Clicking OK fixes the mess, but still looking for a solution to this workaround, though… Any ideas?
Remove $ace1 and remove these lines;
All you want is to add the Deny Apply right. So you don't need to change the ACL on the Sysvol policy folder and you also do not want to remove the Read rights.
$ace1 removes the Read policy rights.
Final code is this: