Good Morning,
So I am having a bit of trouble with this code. I have a gMSA setup to take ownership of Group Policy Objects. I have given the gMSA rights in Group Policy on all Domain Controllers to "Take Ownership of files and other objects". The taking ownership part works like a charm. However the second part of the script, sets permissions using the Set-GPPermissions and is supposed to give two groups access to every GPO in the domain but it doesn't seem to work.
Try {
[void][TokenAdjuster]
} Catch {
$AdjustTokenPrivileges = @"
using System;
using System.Runtime.InteropServices;
public class TokenAdjuster
{
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr
phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name,
ref long pluid);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public static bool AddPrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}
}
public static bool RemovePrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_DISABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}
}
}
"@
Add-Type $AdjustTokenPrivileges
}
#Activate necessary admin privileges to make changes without NTFS perms
[void][TokenAdjuster]::AddPrivilege("SeRestorePrivilege") #Necessary to set Owner Permissions
[void][TokenAdjuster]::AddPrivilege("SeBackupPrivilege") #Necessary to bypass Traverse Checking
[void][TokenAdjuster]::AddPrivilege("SeTakeOwnershipPrivilege") #Necessary to override FilePermissions
# Import the required modules to perform Get-ADOrganizationalUnit & Get-GPO
Import-Module ActiveDirectory,GroupPolicy
$NewOwner = (Get-ADServiceAccount SVC._DA002).SamAccountName
$NewOwnerSID =(Get-ADServiceAccount SVC._DA002).SID
$Domains = (Get-ADForest).Domains
Function zChange-GpoOwner {
Param (
[Parameter(Mandatory=$true)]
[string]$NewOwnerSamAccountName,
[Parameter(Mandatory=$false)]
[string]$ServerToMakeChangeOn
)
[string]$baseDN = (Get-ADDomain $Domain).DistinguishedName
[string]$SearchBase = "CN=Policies,CN=System," + (Get-ADDomain $Domain).DistinguishedName
$GroupPolicyObjects = Get-ADObject -Filter * -SearchBase "$SearchBase" -Server $Domain -Properties objectClass,CanonicalName | Where {$_.objectClass -eq 'groupPolicyContainer'}
ForEach($GroupPolicyObject in $GroupPolicyObjects){
$GroupPolicyObjectDN = $GroupPolicyObject.DistinguishedName
#$SecurityPrincipal = new-object System.Security.Principal.NTAccount("$DomainNetBiosName", "$NewOwnerSamAccountName")
#[System.Security.Principal.NTAccount]$IdentityReference = $SecurityPrincipal
if($ServerToMakeChangeOn){
$DN = $ServerToMakeChangeOn + "/" + $GroupPolicyObjectDN
}else{
$DN = $GroupPolicyObjectDN
}
$guidNull = new-object Guid 00000000-0000-0000-0000-000000000000
$ADObject = [ADSI]"LDAP://$DN"
$ace = new-object System.DirectoryServices.ActiveDirectoryAccessRule $NewOwnerSID,"WriteDacl","Allow",$guidNull
$ADObject.ObjectSecurity.AddAccessRule($ace)
$aclObject = get-acl -Path ADDOM:$SearchBase
$aclObject.SetOwner([Security.Principal.NTaccount]($NewOwnerSamAccountName))
$ADObject.CommitChanges()
set-acl -path ADDOM:$GroupPolicyObjectDN -AclObject $aclObject
#$aclObject.SetOwner($IdentityReference)
}
}
# For every GPO in domain, add the "Domain Group Policy Editors" group and grant the "Edit Settings" permission.
ForEach ($Domain in $Domains){
Import-Module ActiveDirectory
New-PSDrive -Name ADDOM -PSProvider ActiveDirectory -Server $Domain -Scope Global -Root "//ROOTDSE/" | Out-Null
$DomainNetBiosName = (Get-ADDomain $Domain).NetBIOSName
$DC = (Get-ADDomainController -Discover -DomainName $Domain).HostName
zChange-GpoOwner -NewOwnerSamAccountName "A1\$NewOwner" -ServerToMakeChangeOn $DC
ForEach ($GPO in Get-GPO -All -Domain $Domain) {
$GPO = $GPO.DisplayName
Write-Host $GPO
Set-GPPermissions "$GPO" -Replace -PermissionLevel GpoEditDeleteModifySecurity -TargetName "$DomainNetBiosName\Group Policy Rights - Full Control" -TargetType Group -DomainName $Domain
Set-GPPermissions "$GPO" -Replace -PermissionLevel GpoEdit -TargetName "$DomainNetBiosName\Group Policy Rights - Edit" -TargetType Group -DomainName $Domain
}
Remove-PSDrive ADDOM
}
User contributions licensed under CC BY-SA 3.0