Skip to content

Instantly share code, notes, and snippets.

@DexterPOSH
Created April 14, 2015 17:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DexterPOSH/7b666c7078e2af604d0c to your computer and use it in GitHub Desktop.
Save DexterPOSH/7b666c7078e2af604d0c to your computer and use it in GitHub Desktop.
The Function uses AD PS PSmodule to hunt for User accounts which have Inheritance disabled
<#
.Synopsis
The Function uses AD PS PSmodule to hunt for User accounts which have Inheritance disabled
.DESCRIPTION
In AD if the Users have Inheritance disabled on them then this Function will help you hunt those acounts
In addition it will also check if the Users are part of any Protected Group and report them (if any) because of
which the Inheritance is disabled. This is expected but sometimes the User might be part of a Group which is nested
member of a Protected Group, then this Function will list out all the ProtectedGroups too.
The Function needs AD PowerShell Module installed in order to run at the moment.
.EXAMPLE
PS>Get-ADUserWithInheritanceDisabled -SamAccountName 'dexterposh','test123'
SamAccountname : DexterPOSH
UserPrincipalname : DexterPOSH@dex.com
IsAdmin : True
InheritanceDisabled : True
ProtectedGroup1 : CN=Schema Admins,CN=Users,DC=dex,DC=com
ProtectedGroup2 : CN=Administrators,CN=Builtin,DC=dex,DC=com
ProtectedGroup3 : CN=Enterprise Admins,CN=Users,DC=dex,DC=com
ProtectedGroup4 : CN=Domain Admins,CN=Users,DC=dex,DC=com
SamAccountname : test123
UserPrincipalname : test123@dex.com
IsAdmin : True
InheritanceDisabled : True
ProtectedGroup1 : CN=NestedGroup2,CN=Users,DC=dex,DC=com
Example of supplying SamAccountName list to the Function
.EXAMPLE
PS>Get-ADUserWithInheritanceDisabled -Filter * -SearchBase 'OU=ExchangeUsers,Dc=Dex,Dc=Com' -SearchScope Subtree
SamAccountname : DexterPOSH
UserPrincipalname : DexterPOSH@dex.com
IsAdmin : True
InheritanceDisabled : True
ProtectedGroup1 : CN=Schema Admins,CN=Users,DC=dex,DC=com
ProtectedGroup2 : CN=Administrators,CN=Builtin,DC=dex,DC=com
ProtectedGroup3 : CN=Enterprise Admins,CN=Users,DC=dex,DC=com
ProtectedGroup4 : CN=Domain Admins,CN=Users,DC=dex,DC=com
This example illustrates the use of -Filter, -SearchBase & -SearchScope parameter which are essentially passed on to the Get-ADUser to fetch Users.
Once the Users are got the Function processes them.
.EXAMPLE
PS>Get-ADUserWithInheritanceDisabled -LDAPFilter '(&(objectCategory=person)(objectClass=user)(name=test*))' -SearchBase 'OU=ExchangeUsers,Dc=Dex,Dc=Com'
SamAccountname : test123
UserPrincipalname : test123@dex.com
IsAdmin : True
InheritanceDisabled : True
ProtectedGroup1 : CN=NestedGroup2,CN=Users,DC=dex,DC=com
One can use the LDAPFilter , the same you specify with the Get-ADUser
.INPUTS
System.String[]
.OUTPUTS
System.Management.Automation.PSObject
.NOTES
Author - Deepak Dhami [aka DexterPOSH]
Blog - www.dexterposh.com
#>
Function Get-ADUserWithInheritanceDisabled
{
[CmdletBinding(DefaultParameterSetName='SamAccountName',
PositionalBinding = $False)]
[Alias()]
[OutputType([PSCustomObject[]])]
Param
(
# Specify SamAccountName(s) to be processed
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
ParameterSetName='SamAccountName')]
[ValidateNotNullOrEmpty()]
[String[]]$SamAccountName,
#Specify the Filter to be used to search AD Users (same as the one with Get-ADUser)
[Parameter(Mandatory,
ParameterSetName='Filter')]
[ValidateNotNullOrEmpty()]
[String]
$Filter,
#Specify the LDAPFilter to be used, similar to the one used to
[Parameter(Mandatory,
ParameterSetName='LDAPFilter')]
[ValidateNotNullOrEmpty()]
[String]
$LDAPFilter,
# Specifies an Active Directory path to search under [ParameterSet - Filter & LDAPFilter]
[Parameter(ParameterSetName='Filter')]
[Parameter(ParameterSetName='LDAPFilter')]
[ValidateNotNullOrEmpty()]
[String]
$SearchBase,
#Specify the SearchScope to search for Users. Similar to one you specify to Get-ADUser [ParameterSet - Filter & LDAPFilter]
[Parameter(ParameterSetName='Filter')]
[Parameter(ParameterSetName='LDAPFilter')]
[ValidateSet('Base','OneLevel','Subtree')]
[String]
$SearchScope
)
Begin
{
TRY {
#Explicit Check that the AD PowerShell Module is installed
Write-verbose -Message "[BEGIN] : Checking if the AD Mo dule is available on the $env:Computername"
If (Get-Module -Name ActiveDirectory -ListAvailable)
{
if ( ! (get-Module -Name ActiveDirectory)) {
Write-verbose -Message "[BEGIN] : AD Module Found , Explicitly Importing it "
Import-Module -Name ActiveDirectory -ErrorAction stop
}
Write-Verbose -Message "[BEGIN] : Checking if the AD Module loaded the PSDrive"
$null = Get-PSDrive -PSProvider ActiveDirectory -ErrorAction stop
}
else
{
Write-Error -Message 'AD Module not installed' -ErrorAction stop
}
#Create an Array of the Protected AD SecurityGroups , this will return a collection of group names
$ProtectedGroups = Get-ADGroup -Filter 'admincount -eq 1' -ErrorAction Stop | select -ExpandProperty DistinguishedName
#define the ScriptBlock which will process an AD User
$ProcessUserScriptBlock = {
param($user)
if ($user.admincount)
{
#The AdminCount attribute is set which means it is part of a Group which is Protected
# The Inheritance will be disabled automatically for this Account
if ($Comparison = Compare-Object -ReferenceObject $ProtectedGroups -DifferenceObject $user.MemberOf -IncludeEqual -ExcludeDifferent)
{
$ADProtectedGroups = @($comparison | select -ExpandProperty inputobject)
$object = [pscustomobject]@{
SamAccountname = $user.SamAccountName;
UserPrincipalname = $user.UserPrincipalName;
IsAdmin = $true; # this has been already checked
InheritanceDisabled = $true
}
for ($i=0; $i -lt $ADProtectedGroups.Count ; $i++)
{
Add-Member -InputObject $object -MemberType NoteProperty -Name "ProtectedGroup$($i+1)" -Value $ADProtectedGroups[$i]
}
Write-Output -InputObject $object
}
}
else
{
#If the AdminCount attribute is not = 1, then let's check if the Inheritance is disabled.
if ($user.NTSecurityDescriptor.AreAccessRulesProtected) {
[pscustomobject]@{
SamAccountname = $user.SamAccountName;
UserPrincipalname = $user.UserPrincipalName;
IsAdmin = $false; # this has been already checked
InheritanceDisabled = $true #this is checked too
}
}
}
} #end ProcessUserScriptBlock
}
CATCH
{
throw $PSItem.exception
}
}
Process
{
Switch -Exact ($PSCmdlet.ParameterSetName) {
'SamAccountName' {
Write-Verbose -Message "[PROCESS] : ParameterSet Name Resolved to SamAcountName"
foreach ($Name in $SamAccountName) {
Write-verbose -Message "[PROCESS] : Processing the SamAccountName -> $Name"
TRY {
Write-verbose -Message "[PROCESS] : Retrieving the AD User detail"
$User = Get-ADUser -Identity $name -Properties NTSecurityDescriptor,Admincount,MemberOf -ErrorAction Stop
Write-Verbose -Message "[PROCESS] : Checking if the User -> $name has Inheritance Disabled"
& $ProcessUserScriptBlock -user $User
} #End TRY
CATCH {
Write-Warning -Message " [PROCESS] : SamAccountName : $PSItem.exception "
}
}
}
'Filter' {
Write-Verbose -Message "[PROCESS] : ParameterSet Name Resolved to Filter"
Try {
$Users = Get-ADUSer @PSBoundParameters -Properties NTSecurityDescriptor,Admincount,MemberOf -ErrorAction stop
Write-Verbose -Message "[PROCESS] : Found $($Users.Count) users as per criteria"
foreach ($user in $Users) {
Write-Verbose -Message "[PROCESS] : Checking if the User -> $($User.name) has Inheritance Disabled"
& $ProcessUserScriptBlock -user $user
}
} #end Try
Catch {
Write-Warning -Message " [PROCESS] : Filter : $PSItem.exception "
}
}
'LDAPFilter' {
Write-Verbose -Message "[PROCESS] : ParameterSet Name Resolved to LDAPFilter"
Try {
$Users = Get-ADUSer @PSBoundParameters -Properties NTSecurityDescriptor,Admincount,MemberOf -ErrorAction stop
Write-Verbose -Message "[PROCESS] : Found ($Users.Count) users as per criteria"
foreach ($user in $Users) {
Write-Verbose -Message "[PROCESS] : Checking if the User -> $name has Inheritance Disabled"
& $ProcessUserScriptBlock -user $user
}
}
Catch {
Write-Warning -Message $PSItem.exception
}
}
}
}
End
{
Write-Verbose -Message "[END] : Ending Function"
Remove-Module ActiveDirectory -ErrorAction SilentlyContinue
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment