Script: Fixing Orphaned AdminSDHolder Accounts

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 “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

.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 } }