To-Do.txt

# Grant permission to manage list of UPN Suffixes
####################################################################################################

$NameTargetOU = "CN=Partitions,CN=Configuration," + $DomainRootDN
    
        $ACLTargetOU = Get-Acl -Path "AD:/$NameTargetOU"
        $ACLTargetOU.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SidDelegate, "ReadProperty,WriteProperty", "Allow", $guidmap["uPNSuffixes"], "All"))
        Set-Acl -AclObject $ACLTargetOU -Path "AD:/$NameTargetOU"
        write-log "Permission to manage UPN Suffixes - ACE updated for: $NameDelegate on $NameTargetOU"




# Grant Full Control on GPO Central Store and Netlogon\Sources folder
####################################################################################################

$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ZoneNetBIOSName\$NameDelegate", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")


        [string]$Path = "\\$ZoneDNSName\SYSVOL\$ZoneDNSName\Policies\PolicyDefinitions"
        $ACLTargetOU = Get-Acl $Path
        
        $ACLTargetOU.SetAccessRule($AccessRule)
        $ACLTargetOU | Set-Acl $Path


# Grant permission to Reanimate tombstones in the domain
####################################################################################################

$NameDelegate = "DL_Tier0_TombstoneManagement"
$SidDelegate = New-Object System.Security.Principal.SecurityIdentifier (Get-ADGroup $NameDelegate).SID

Try {
        $NameTargetOU = $OURootDN
    
        $ACLTargetOU = Get-Acl -Path "AD:/$NameTargetOU"
        $ACLTargetOU.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SidDelegate, "ReadProperty", "Allow", "All", $nullGUID))
        $ACLTargetOU.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SidDelegate, "ExtendedRight", "Allow", $extendedrightsmap["Reanimate tombstones"], "All"))
        Set-Acl -AclObject $ACLTargetOU -Path "AD:/$NameTargetOU"
        write-log "Permission to reanimate tombstones - ACE updated for: $NameDelegate on $NameTargetOU"
    }
    Catch {
        Write-Log "Failed to set permission to reanimate tombstones for $NameDelegate on $NameTargetOU. - $($_.Exception.Message) at line $($_.InvocationInfo.ScriptLineNumber) char $($_.InvocationInfo.OffsetInLine)" Warning
    }

# Grant permission to manage deleted objects
    Try {
        $cmd = 'dsacls “' + 'CN=Deleted Objects,' + $DomainRootDN + '” /takeownership'
        Invoke-Expression $cmd
        # $cmd = 'dsacls “' + 'CN=Deleted Objects,' + $DomainRootDN + '" /g ' + (get-addomain).NetBIOSName + '\' + $NameDelegate + ':GA /I:T'
        $cmd = 'dsacls “' + 'CN=Deleted Objects,' + $DomainRootDN + '" /g ' + (get-addomain).NetBIOSName + '\' + $NameDelegate + ':LCRPWP /I:T'
        Invoke-Expression $cmd
        write-log "Permission to managed deleted objects - ACE updated for: $NameDelegate on $NameTargetOU"
    }
    Catch {
        Write-Log "Failed to set permission on deleted objects for $NameDelegate on $NameTargetOU. - $($_.Exception.Message) at line $($_.InvocationInfo.ScriptLineNumber) char $($_.InvocationInfo.OffsetInLine)" Warning
    }


# Sites & Services - DNS
####################################################################################################

$NameTargetOU = "CN=Sites,CN=Configuration," + $DomainRootDN

$ACLTargetOU.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SidDelegate, "GenericAll", "Allow", "Descendents", $guidmap["msDNS-ServerSettings"]))



# Give Create/delete Domain DNS Zones
####################################################################################################
    Try {
        $NameTargetOU = "CN=MicrosoftDNS,DC=DomainDnsZones,$DomainRootDN"
    
        $ACLTargetOU = Get-Acl -Path "AD:/$NameTargetOU"
        Foreach ($ace in $ACLTargetOU.Access) {
            if ($ace.IdentityReference -match 'dnsAdmins') {
                $ACLTargetOU.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SidDelegate, $ace.ActiveDirectoryRights, $ace.AccessControlType , $ace.ObjectType, "All"))
            }
        }
        Set-Acl -AclObject $ACLTargetOU -Path "AD:/$NameTargetOU"
        write-log "Permission to create Domain DNS Zones - ACE updated for: $NameDelegate on $NameTargetOU"
    }
    Catch {
        Write-Log "Failed to set permission to create Domain DNS Zones for $NameDelegate on $NameTargetOU. - $($_.Exception.Message) at line $($_.InvocationInfo.ScriptLineNumber) char $($_.InvocationInfo.OffsetInLine)" Warning
    }


# Grant permission to manage existing Domain Level DNS Zones
####################################################################################################
    Try {
        $DNSZones = Get-ADObject -LDAPFilter "(objectClass=dnsZone)" -SearchBase "CN=MicrosoftDNS,DC=DomainDnsZones,$DomainRootDN" -SearchScope Subtree
        Write-Log "Granting permission to $NameDelegate on existing Domain Level DNS Zones"
        ForEach ($zone in $DNSZones) {
            Write-Log " Zone=$($zone.name)" -information
            $NameTargetOU = $zone.distinguishedName
            $NameTargetOU | Remove-Delegation
        
            $ACLTargetOU = Get-Acl -Path "AD:/$NameTargetOU"
            Foreach ($ace in $ACLTargetOU.Access) {
                if ($ace.IdentityReference -match 'dnsAdmins') {
                    $ACLTargetOU.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SidDelegate, $ace.ActiveDirectoryRights, $ace.AccessControlType , $ace.ObjectType, "All"))
                }
            }
            Set-Acl -AclObject $ACLTargetOU -Path "AD:/$NameTargetOU"
        }
    }
    Catch {
        Write-Log "Failed to set permission to manage exiting Domain DNS Zones $NameDelegate on $NameTargetOU. - $($_.Exception.Message) at line $($_.InvocationInfo.ScriptLineNumber) char $($_.InvocationInfo.OffsetInLine)" Warning
    }



# Allow 'Read Terminal Server License'
####################################################################################################

$ACLTargetOU = Get-Acl -Path "AD:/$NameTargetOU"
        
        $ACLTargetOU.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SidDelegate, "ReadProperty,WriteProperty", "Allow", $extendedRightsMap["Terminal Server License server"], "Descendents", $guidmap["user"]))
        Set-Acl -AclObject $ACLTargetOU -Path "AD:/$NameTargetOU"

        write-log "Read Terminal Server License - ACE updated for: SELF on $NameTargetOU"





# Deny Change Owner to OWNER RIGHTS for all objects
####################################################################################################

 $ACLTargetOU = Get-Acl -Path "AD:/$NameTargetOU"
        
        $ACLTargetOU.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SidDelegate, "WriteOwner", "Deny", "Descendents", $nullGUID))
        Set-Acl -AclObject $ACLTargetOU -Path "AD:/$NameTargetOU"

        write-log "Deny Change Owner - ACE updated for: OWNER RIGTHS on $NameTargetOU"



# AdminSDholder
####################################################################################################
function FixAdminSDHolder
{

    $RootDSE = New-Object -TypeName System.DirectoryServices.DirectoryEntry -ArgumentList "LDAP://RootDSE"
    $configurationNamingContext = $RootDSE.Properties.Item('configurationNamingContext')
    $DirectoryService = New-Object -TypeName System.DirectoryServices.DirectoryEntry -ArgumentList "LDAP://CN=Directory Service,CN=Windows NT,CN=Services,$configurationNamingContext"
    $dsHeuristics = $DirectoryService.Properties.Item('dsHeuristics').Value

    if ($dsHeuristics)
    {
        Write-Output -InputObject "`nCurrent dsHeuristics value: $dsHeuristics`n"
        
        # Remove permissions for all operator groups
        if ($dsHeuristics.Length -lt 16)
        {
            $dsHeuristics += '000000000100000f'.Substring($dsHeuristics.Length)
        }
        # Implement mitigations in CVS-2021-4229 by setting LDAPAddAutZVerifications and LDAPOwnerModify to 1.
        if ($dsHeuristics.Length -lt 29)
        {
            $dsHeuristics += '0002000000011'.Substring($dsHeuristics.Length -16)
        }
    }
    else
    {
        Write-Output -InputObject "`nCurrent dsHeuristics value: null`n"
        $dsHeuristics = '000000000100000f0002000000011'
    }


    Write-Output -InputObject "`nResulting dsHeuristics value: $dsHeuristics`n"
    $DirectoryService.Put('dsHeuristics', $dsHeuristics)
    $DirectoryService.SetInfo()
}

Function Invoke-ADSDPropagation{
    <#
    .SYNOPSIS
        Invoke a SDProp task on the PDCe.
    .DESCRIPTION
        Make an LDAP call to trigger SDProp.
    .EXAMPLE
        Invoke-ADSDPropagation
        By default, RunProtectAdminGroupsTask is used.
    .EXAMPLE
        Invoke-ADSDPropagation -TaskName FixUpInheritance
        Use the legacy FixUpInheritance task name for Windows Server 2003 and earlier.
    .PARAMETER TaskName
        Name of the task to use.
            - FixUpInheritance for legacy OS
            - RunProtectAdminGroupsTask for recent OS
    
    #>
        [CmdletBinding()]
        Param(
            [ValidateSet('RunProtectAdminGroupsTask','FixUpInheritance')]
            [String]$TaskName = 'RunProtectAdminGroupsTask'
        )
    
        try{
            $DomainName = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
            $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext('domain',$DomainName)
            $DomainObject = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
        
            Write-Verbose -Message "Detected PDCe is $($DomainObject.PdcRoleOwner.Name)."
            $RootDSE = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$($DomainObject.PdcRoleOwner.Name)/RootDSE")
            $RootDSE.UsePropertyCache = $false
            $RootDSE.Put($TaskName, "1") # RunProtectAdminGroupsTask & fixupinheritance
            $RootDSE.SetInfo()
        }
        catch{
            throw "Can't invoke SDProp on $($DomainObject.PdcRoleOwner.Name) !"
        }
    }