Using PowerShell to take ownership/change permissions of GPOs

0

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
}
powershell
active-directory
group-policy
asked on Stack Overflow Aug 16, 2020 by Jacob Pagano

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0