1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 | $users = Get-ADObject -LDAPFilter '(&(primarygroupId=*)(!(|(primarygroupID=513)(primarygroupID=515)(primarygroupID=516)(primarygroupID=521)))(!(Name=Guest)))'
$group = Get-ADGroup 'Domain Users' -Properties @('primaryGroupToken')
$users | Set-ADUser -Replace @{
primaryGroupID = $group.primaryGroupToken
}
# Detect and Remove Orphaned SD Admin users
#region Function
<#
.SYNOPSIS
Detects Orphaned SD Admin users, resets admin count attribute and enables inheritable permissions
.Author
Alan.McBurney (+ Ashley Steel)
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
$orphans = Get-OrphanAdminSdHolderUsers -OutputToPsHost
$orphans | Clear-OrphanAdminSdHolderUser
.Notes
To Do list: Enable logging
Originally acquired from here: https://everythingsysadmin.wordpress.com/2014/08/27/fixing-orphaned-adminsdholder-accounts/
#>
#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 -FilterScript {
$_.name -eq $name
})
{
Import-Module -Name $name
$null = $True
}
else
{
Write-Host ActiveDirectory PowerShell Module Not Available -ForegroundColor Red
}
} # end if not module
else
{
$null = $True
} #module already loaded
} #end function get-MyModule
Get-MyModule -name 'ActiveDirectory'
Function Set-Inheritance
{
[cmdletbinding()]
Param($DistinguishedName)
$Acl = Get-Acl -Path ('AD:\{0}' -f $DistinguishedName)
If ($Acl.AreAccessRulesProtected -eq $True)
{
$Acl.SetAccessRuleProtection($False, $True)
Set-Acl -AclObject $Acl -Path ('AD:\{0}' -f $DistinguishedName)
}
}
Function Get-FlaggedAsAdminGroups
{
Get-ADGroup -LDAPFilter '(adminCount=1)'
}
Function Get-FlaggedAsAdminUsers
{
Get-ADUser -LDAPFilter '(adminCount=1)' | Where-Object -FilterScript {
$_.Name -notlike 'krbtgt'
}
}
Function Get-AdminGroupUsers
{
$RawAdminUsers = ForEach ($group in Get-FlaggedAsAdminGroups)
{
# Get all users from all admin groups recursively
Get-ADGroupMember $group -Recursive | Where-Object -FilterScript {
$_.ObjectClass -eq 'User'
}
# ...then sort them by distinguishedName to ensure accurate -Unique results (because some users might be in multiple protected groups)
}
$RawAdminUsers |
Sort-Object -Property distinguishedname |
Select-Object -Unique
}
Function Get-OrphanAdminSdHolderUsers
{
[cmdletbinding()]
param(
[switch]$OutputToPsHost
)
#Get List of Admin Users (Past and Present)
$UsersFlaggedAsAdmin = Get-FlaggedAsAdminUsers
$UsersInAdminGroups = Get-AdminGroupUsers
#Compare $AdminUsers to $Admins and place in appropriate hash table
$OrphanedUsers = ForEach ($User in $UsersFlaggedAsAdmin)
{
If ($UsersInAdminGroups.samAccountName -notcontains $User.samAccountName)
{
if ( $OutputToPsHost.IsPresent )
{
Write-Host -Object ("ORPHAN`t`t{0}" -f $User.samAccountName)
}
$User
}
else
{
if ( $OutputToPsHost.IsPresent )
{
Write-Host -Object ("STILL ADMIN`t{0}" -f $User.samAccountName)
}
}
}
return $OrphanedUsers
}
Function Clear-OrphanAdminSdHolderUser
{
[cmdletbinding()]
param(
[parameter(ValueFromPipeline)]
[Microsoft.ActiveDirectory.Management.ADPrincipal[]]$OrphanUser,
[bool]$Confirm = $True
)
Begin {
}
Process {
if ( $OrphanUser.SamAccountName -like 'krbtgt' )
{
Write-Warning -Message "krbtgt has been skipped; it's unlikely you actually wish to demote this from being a protected user"
}
else
{
$Proceed = $False
if ( $Confirm )
{
$Proceed = (Read-Host -Prompt ('Do you wish to clear adminCount from {0}? Y or anything else' -f $OrphanUser.samAccountName)).toLower() -eq 'y'
}
else
{
$Proceed = $True
}
if ( $Proceed )
{
Write-Host -Object ('{0}: Clearing AdminCount...' -f $OrphanUser.SamAccountName) -NoNewline
$OrphanUser | Set-ADUser -Clear {
AdminCount
} -ErrorAction Continue -ErrorVariable ClearError
if ( $ClearError.Count -gt 0 )
{
Write-Error ('{0} | Set-ADUser -Clear {AdminCount} failed. See error above' -f $OrphanUser.samAccountName)
exit
}
else
{
Write-Host -Object 'OK...Enabling Inheritence...' -NoNewline
Set-Inheritance $OrphanUser -ErrorAction Continue -ErrorVariable InheritenceError
if ( $InheritenceError.Count -gt 0)
{
Write-Error ('Set-Inheritence -DistinguishedName {0} failed. See error above' -f $OrphanUser.distinguishedname)
exit
}
else
{
Write-Host -Object 'OK'
}
}
}
else
{
Write-Host -Object ('{0} skipped' -f $OrphanUser.samAccountName)
}
}
}
}
#endregion Function
$orphans = Get-OrphanAdminSdHolderUsers -OutputToPsHost
$orphans | Clear-OrphanAdminSdHolderUser
|