@GitHub Copilot - Welcome @BanterBoy, I’m your Copilot and I’m here to help you get things done faster. I can identify issues, explain and even improve code.

You can ask generic questions, but what I’m really good at is helping you with your code. For example:

Generate unit tests for my code Explain the selected code Propose a fix for the bugs in my code If you want to learn more about my capabilities and limitations, check out the Copilot documentation.

I’m powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve.

@BanterBoy: - Explain what the script does and why it is useful.

@GitHub Copilot -


  This script will reset the inheritance flag and clear the
  AdminCount attribute for objects no longer protected by the

  Output will be written to a csv file that can be imported
  into Excel for reporting.

  The script can run in "report only" mode, so that you are first
  able to understand the current state before taking any action.
  You then have two options:
  1) Manually set each account.
  2) Run this script to take action and reset the inheritance flag
     and clear the AdminCount attribute for all existing accounts
     that have the AdminCount attribute set to 1.
     Any objects that should genuinely be protected will be
     re-protected when the AdminSDHolder next cycles (within 1 hour
     by default).

  Script Name: Cleanup-AdminSDHolder.ps1
  Author: Tony Murray
  Version: 1.0
  Date: 28/08/2013

  Requires PowerShell 2.0 and above.


    To Report ONLY:
      Cleanup-AdminSDHolder.ps1 -action ReportOnly

    To take action:


if ([String]::IsNullOrEmpty($Action)) {
    $ReportOnly = $False
else {
    If ($Action -eq "ReportOnly") {
        $ReportOnly = $True
    else {
        $ReportOnly = $False

# Get the script path
$ScriptPath = { Split-Path $MyInvocation.ScriptName }
$ReferenceFile = $(&$ScriptPath) + "\AdminSDHolderReport.csv"

$array = @()
$objectclasses = @{}

$ProtectedGroups = @("Schema Admins", "Enterprise Admins", "Cert Publishers", "Domain Admins", "Account Operators", "Print Operators", "Administrators", "Server Operators", "Backup Operators")

# Import the AD module
Import-Module ActiveDirectory

# Find objects that appear to be protected in AD
$probjs = Get-ADObject -LDAPFilter "(admincount=1)" | sort-object ObjectClass, Name
$bcount = $probjs.count
if ($bcount) {
    If ($ReportOnly -eq $False) {
        Write-Host -ForegroundColor Green "Protected object count before change is $bcount"
    else {
        Write-Host -ForegroundColor Green "Protected object count is $bcount"
    } # end if
else {
    Write-Host -ForegroundColor Green "No objects are currently protected - nothing to do"
} # end if
Write-Host " "

# Change to the AD drive
Set-Location AD:

# Loop through protected objets to set inheritance flag
# and clear the adminCount value
foreach ($probj in $probjs) {
    $dn = $probj.distinguishedname
    If ($($"CNF:") -eq $False) {
        $name = $($
    else {
        $name = [string]::join("\0A", ($($"`n")))
    } # end if
    $class = $probj.ObjectClass

    # Create a hashtable to capture a count of each objectclass
    If (!($objectclasses.ContainsKey($class))) {
        $objectclasses = $objectclasses + @{$class = 1 }
    else {
        $value = $objectclasses.Get_Item($class)
        $value ++
        $objectclasses.Set_Item($class, $value)
    } # end if

    If ($dn.Contains("CNF:") -eq $False) {
        If ($ProtectedGroups -notcontains $name) {
            $acl = Get-Acl $dn
            if ($acl.AreAccessRulesProtected) {
                If ($ReportOnly -eq $False) {
                    Write-Host -ForegroundColor Yellow "$class`t$dn has inheritance blocked - we will remove the block"
                    $acl.SetAccessRuleProtection($false, $false);
                    #set-acl -aclobject $acl $dn
                    # We need to clear the adminCount attribute too
                    #Set-ADObject -Identity $dn -Clear adminCount
                else {
                    Write-Host -ForegroundColor Yellow "$class`t$dn has inheritance blocked"
                } # end if
            } # end if
        else {
            Write-Host -ForegroundColor Yellow "$class`t$dn is a default protected group"
        } # end if
    else {
        Write-Host -ForegroundColor Red "$class`t$dn cannot be processed"
    }# end if

    $obj = New-Object -TypeName PSObject
    $obj | Add-Member -MemberType NoteProperty -Name "Class" -Value $class
    $obj | Add-Member -MemberType NoteProperty -Name "Name" -Value $name
    $obj | Add-Member -MemberType NoteProperty -Name "DN" -Value $dn
    $array += $obj

} # end foreach

Write-Host -ForegroundColor Green "`nA break down of the $bcount objects processed:"
$objectclasses.GetEnumerator() | Sort-Object Name | ForEach-Object {
    Write-Host -ForegroundColor Green "- $($_.key): $($_.value)"

# Write-Output $array | Format-Table
$array | Export-Csv -notype -path "$ReferenceFile" -Delimiter ';'

# Remove the quotes
(Get-Content "$ReferenceFile") | ForEach-Object { $_ -replace '"', "" } | Out-File "$ReferenceFile" -Force -Encoding ascii

If ($ReportOnly -eq $False) {
    # Count the number of protected objects
    $acount = (Get-ADObject -LDAPFilter "(admincount=1)").count
    Write-Host " "
    if ($acount) {
        Write-Host -ForegroundColor Green "Protected object count after change is $acount"
    else {
        Write-Host -ForegroundColor Green "No objects are currently protected"
    } # end if
} # end if

Back to Top


Please feel free to copy parts of the script or if you would like to download the entire script, simple click the download button. You can download the complete repository in a zip file by clicking the Download link in the menu bar on the left hand side of the page.

Report Issues

You can report an issue or contribute to this site on GitHub. Simply click the button below and add any relevant notes. I will attempt to respond to all issues as soon as possible.


Back to Top