Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# Associated blog post : https://blog.hophouse.fr/_posts/CheckResetPasswordRights.html
function Get-ADAllUserGroupMembership {
<#
.SYNOPSIS
Recursively retrieve all the groups where a specified group belongs to.
.EXAMPLE
PS> Get-ADAllUserGroupMembership -Server 10.10.10.10 -GroupName custom_admin
.PARAMETER Server
Domain Controller where to run commands.
.PARAMETER GroupName
Group where the function will dig.
#>
[CmdletBinding()]
param(
[parameter(mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string]$Server,
[parameter(mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string]$GroupName
)
$GroupMembership = @()
$GroupObject = Get-ADGroup -Server $Server -Identity $GroupName -Properties MemberOf,objectSid
[array]$GroupMembership += $GroupObject
$GroupMemberObject = ($GroupObject).MemberOf
if($GroupMemberObject.count -eq 0) {
return $GroupMembership
}
foreach ($grp in $GroupMemberObject) {
[array]$GroupMembership += Get-ADAllUserGroupMembership -Server $Server -GroupName $grp
}
return $GroupMembership | Sort-Object -Unique
}
function Invoke-CheckResetUserPasswordRight {
<#
.SYNOPSIS
Retrieve the users that the specified users are able to reset the password.
.EXAMPLE
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1 -Filter 'enabled -eq $true'
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1 -Filter "Name -like '*user*'"
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1,User2 -SearchBase "OU=Admins,DC=lab,DC=local"
PS> Invoke-CheckResetUserPasswordRight -Server 10.10.10.10 -Users User1,User2,User3 -NoGroupCheck -OnlyResult
.PARAMETER Server
Domain Controller where to run commands.
.PARAMETER Users
List of users to check.
.PARAMETER Filter
Filter applied to the Get-AdUser function.
.PARAMETER Filter
Apply a search base to the function Get-AdUser.
.PARAMETER OnlyResults
Display only the samAccountName of users where specified users can reset the password.
.PARAMETER OnlyResults
Search only direct right to reset password and do not include groups of the user.
#>
[CmdletBinding()]
[OutputType([hashtable])]
param(
[parameter(mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string]$Server,
[parameter(mandatory=$True)]
[ValidateNotNullOrEmpty()]
[array]$Users,
[parameter(mandatory=$False)]
[string]$Filter = "*",
[parameter(mandatory=$False)]
[ValidateNotNullOrEmpty()]
[string]$SearchBase = "",
[switch]$OnlyResults,
[switch]$NoGroupCheck
)
try {
Import-Module ActiveDirectory
}
catch {
Write-Host "[!] Please install the ActiveDirectory module"
return
}
$ResultRestPasswordRight = @()
$objects = @()
# Default values for ObjectType GUID - CN=User-Force-Change-Password,CN=Extended-Rights,CN=Configuration,DC=lab,DC=local
$RestPasswordRight = "00299570-246d-11d0-a768-00aa006e0529"
#$ChangePasswordRight = "ab721a53-1e2f-11d0-9819-00aa0040529b"
$GenericAllRight = "00000000-0000-0000-0000-000000000000"
# Mount the AD as drive in order to get ACL on its objects
Write-Output "[+] Mount AD drive"
New-PSDrive -Name AD -PSProvider ActiveDirectory -Root "//RootDSE/" -Server $Server | Out-Null
# Get user information
foreach ($User in $Users) {
Echo "[+] Get User informations for $User"
$userInfo = Get-ADUser -Server $Server -Identity $User -Properties MemberOf
if ($userInfo -eq $null) {
return
}
[array]$objects += $userInfo
$userGroups = ($userInfo).MemberOf
if ($NoGroupCheck.IsPresent -eq $True) {
break
}
Write-Output "[+] Get groups for $User"
($userGroups) | ForEach-Object {
[array]$objects += Get-ADAllUserGroupMembership -Server $Server -GroupName $_
}
if ($userGroups.count -ge 1) {
Write-Output "[+] $User belongs to :"
($objects[1..($objects.Length-1)]) | ForEach-Object {
Write-Output " - [$($_.objectSid)] $($_.samAccountName)"
}
} else {
Write-Output " [+] $User does not belong to any group."
}
$objects = ($objects | Sort-Object -Unique)
}
Write-Output "[+] Get all users"
if ($SearchBase -ne "") {
$allUsers = Get-ADUser -Server $Server -Filter $Filter -SearchBase $SearchBase
} else {
$allUsers = Get-ADUser -Server $Server -Filter $Filter
}
Write-Output "[+] Run search on $($allUsers.count) users at $(Get-Date)"
($allUsers) | ForEach-Object {
$targetUser = $_
# Get ACL to reset password right
try {
$aclResetPassword = ((Get-Acl "AD:\$($targetUser.DistinguishedName)" | Select-object Access).access| Where-Object {$_.ObjectType -eq $RestPasswordRight -or $_.InheritedObjectType -eq $ResetPasswordRight -or $_.ObjectType -eq $GenericAllRight})
}
catch { }
($objects) | ForEach-Object {
$object = $_
$acl = $aclResetPassword | Where-Object {$_.IdentityReference -like "*$($object.SamAccountName)" -or $_.IdentityReference -eq $object.SID}
if ($acl -ne $null) {
$properties = @{
From = $object.samAccountName
PasswordResetRight = $true
User = $targetUser.samAccountName
UserIsEnabled = $targetUser.Enabled
}
$obj = New-Object -TypeName psobject -Property $properties
$ResultRestPasswordRight += $obj
}
}
}
Write-Output "[+] Finished search on $($allUsers.count) users at $(Get-Date)"
if ($OnlyResults -eq $True) {
return ($ResultRestPasswordRight).User | Sort-Object -Unique
}
if ($ResultRestPasswordRight.Length -ge 1) {
Write-Output "`r`n[+] CMD : Set-ADAccountPassword -Server $($Server) -identity User -Reset -NewPassword (ConvertTo-SecureString -AsPlainText 'Password' -Force)"
}
return $ResultRestPasswordRight
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment