Alan's sysadmin Blog

Working smarter not harder

Script: Fixing Orphaned AdminSDHolder Accounts

Posted by Alan McBurney on August 27, 2014


This is intended as a follow up to Detecting members of Protected Groups within AD

It seems that no matter how many Exchange or Lync projects I do I always come across the issue of orphaned AdminSDHolders.

To overcome the tedium of detecting and fixing orphaned users I decided to put together a script to automate the task.

This script gets all users that are members of protected groups within AD and compares membership with users that have the AD Attribute AdminCount=1 set. If the user has the AdminCount=1 enabled but is not a member of a protected group within AD then the user is considered orphaned, the AdminCount is reset to 0 and inheritable permissions are enabled.

<#
.SYNOPSIS
Detects Orphaned SD Admin users, resets admin count attribute and enables inheritable permissions

.Author
Alan.McBurney

THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.

Version 1.0, July 10th, 2014

.DESCRIPTION
This script gets all users that are members of protected groups within AD and compares
membership with users that have the AD Attribute AdminCount=1 set.
If the user has the AdminCount=1 enabled but is not a member of a protected group then the user
is considered an orphaned admin user and the AdminCount is reset to 0 and inheritable permissions
are reset

.REFERENCES
"http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/11/hey-scripting-guy-weekend-scripter-checking-for-module-dependencies-in-windows-powershell.aspx">http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/11/hey-scripting-guy-weekend-scripter-checking-for-module-dependencies-in-windows-powershell.aspx</a>
"http://blogs.msdn.com/b/muaddib/archive/2013/12/30/how-to-modify-security-inheritance-on-active-directory-objects.aspx">http://blogs.msdn.com/b/muaddib/archive/2013/12/30/how-to-modify-security-inheritance-on-active-directory-objects.aspx</a>

.EXAMPLE
Reset-OrphanSDUsers

.Notes
To Do list: Enable logging
#>

#Check to Ensure Active Directory PowerShell Module is available within the system
Function Get-MyModule
{
Param([string]$name)
if(-not(Get-Module -name $name))
  {
    if(Get-Module -ListAvailable |Where-Object { $_.name -eq $name })
    {
      Import-Module -Name $name
      $True | Out-Null
    }
    else
    {
      Write-Host ActiveDirectory PowerShell Module Not Available -ForegroundColor Red
    }
  } # end if not module
  else
  {
    $True | Out-Null
  }   #module already loaded
} #end function get-MyModule

Get-MyModule -name "ActiveDirectory"

Function Set-Inheritance
{
Param($ObjectPath)
$Acl = Get-ACL -path "AD:\$ObjectPath"
  If ($Acl.AreAccessRulesProtected -eq $True)
  {
    $Acl.SetAccessRuleProtection($False, $True)
    Set-ACL -AclObject $ACL -path "AD:\$ObjectPath"
  }
}

#Get List of Proected Groups
$AdminGrp = Get-ADGroup -LDAPFilter "(adminCount=1)"

#Get List of Admin Users (Past and Present)
$AdminUsers = Get-ADUser -LDAPFilter "(adminCount=1)"

$Admins = ForEach ($Grp in $AdminGrp) {Get-ADGroupMember $Grp | Where-Object {$_.ObjectClass -eq "User"}}

#Create Empty Hash
$PGUSers = @{}
$OrphanUsers = @{}

#Compare $AdminUsers to $Admins and place in appropriate hash table
ForEach ($User in $AdminUsers)
{
If ($Admins -Match $User.Name)
  {
    $PGUsers.Add($User.Name, "Present")
  }
  Else
  {
    $OrphanUsers.Add($User.SamAccountName, "NotPresent")
  }
}

If ($OrphanUsers.Keys.Count.Equals(0))
{
  $True | Out-Null
}
Else
{
  #Clear AdminCount Attribute
  ForEach ($Orphan in $OrphanUsers.Keys)
  {
    $Orphan
    $ADUser = Get-ADUser $Orphan
    Set-ADUser $Orphan -Clear {AdminCount}
    Set-Inheritance $ADUser
  }
}
Advertisements

One Response to “Script: Fixing Orphaned AdminSDHolder Accounts”

  1. Dan said

    Thanks for this script, very timely for me. Just one modification I had to make, some of our accounts have ( or ) characters in the display name, which was throwing off the regex match in line 81. This fixed it:
    If ($Admins -Match [regex]::escape($User.Name))

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: