fix(Test-ReplicationPermissions): resolve UPN-formatted credentials
Get-ADUser -Identity accepts a DN, GUID, SID, or sAMAccountName - not a UPN. The SID/tokenGroups resolution stripped only a 'DOMAIN\' prefix, so a UPN-formatted credential (user@domain.tld) had no backslash to strip, -Identity threw on the full UPN, and the exception was swallowed by the surrounding catch (Write-Warning + return), silently skipping the entire DCSync ACL pre-check. Now branches on the credential format: DOMAIN\user strips the prefix as before, user@domain.tld resolves via -Filter "UserPrincipalName -eq '...'", and a bare sAMAccountName is used as-is. The follow-up tokenGroups lookup now uses the resolved DistinguishedName instead of re-deriving the username format. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+18
-4
@@ -348,14 +348,28 @@ function Test-ReplicationPermissions {
|
|||||||
|
|
||||||
$callerSids = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
|
$callerSids = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
|
||||||
try {
|
try {
|
||||||
$samName = $Credential.UserName -replace '^.*\\', ''
|
# Get-ADUser -Identity accepts a DN, GUID, SID, or sAMAccountName - but NOT a UPN. A
|
||||||
$adUser = Get-ADUser -Identity $samName -Server $Server -Credential $Credential `
|
# UPN-formatted credential (user@domain.tld) has no backslash, so naively stripping a
|
||||||
|
# 'DOMAIN\' prefix left the full UPN in place, -Identity threw, and this whole pre-check
|
||||||
|
# was silently skipped (caught below) regardless of how the username was typed.
|
||||||
|
$rawUserName = $Credential.UserName
|
||||||
|
if ($rawUserName -match '^[^\\]+\\(.+)$') {
|
||||||
|
$adUser = Get-ADUser -Identity $Matches[1] -Server $Server -Credential $Credential `
|
||||||
-Properties SID, DistinguishedName, adminCount -ErrorAction Stop
|
-Properties SID, DistinguishedName, adminCount -ErrorAction Stop
|
||||||
|
} elseif ($rawUserName -match '@') {
|
||||||
|
$adUser = Get-ADUser -Filter "UserPrincipalName -eq '$rawUserName'" -Server $Server -Credential $Credential `
|
||||||
|
-Properties SID, DistinguishedName, adminCount -ErrorAction Stop | Select-Object -First 1
|
||||||
|
if (-not $adUser) { throw "No AD user found with UserPrincipalName '$rawUserName'." }
|
||||||
|
} else {
|
||||||
|
$adUser = Get-ADUser -Identity $rawUserName -Server $Server -Credential $Credential `
|
||||||
|
-Properties SID, DistinguishedName, adminCount -ErrorAction Stop
|
||||||
|
}
|
||||||
[void]$callerSids.Add($adUser.SID.Value)
|
[void]$callerSids.Add($adUser.SID.Value)
|
||||||
|
|
||||||
# tokenGroups is a constructed attribute containing all SIDs in the user's token,
|
# tokenGroups is a constructed attribute containing all SIDs in the user's token,
|
||||||
# including nested group memberships - more reliable than walking MemberOf recursively
|
# including nested group memberships - more reliable than walking MemberOf recursively.
|
||||||
$adUserWithTokenGroups = Get-ADUser -Identity $samName -Server $Server -Credential $Credential `
|
# Look up by DistinguishedName (unambiguous) rather than re-deriving the username format.
|
||||||
|
$adUserWithTokenGroups = Get-ADUser -Identity $adUser.DistinguishedName -Server $Server -Credential $Credential `
|
||||||
-Properties tokenGroups -ErrorAction Stop
|
-Properties tokenGroups -ErrorAction Stop
|
||||||
foreach ($sidBytes in $adUserWithTokenGroups.tokenGroups) {
|
foreach ($sidBytes in $adUserWithTokenGroups.tokenGroups) {
|
||||||
$sid = New-Object System.Security.Principal.SecurityIdentifier(@([byte[]]$sidBytes), 0)
|
$sid = New-Object System.Security.Principal.SecurityIdentifier(@([byte[]]$sidBytes), 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user