Search code examples
powershellpowershell-5.0

How come my condition determining if a user is in a group always returns as false?


I'm writing a script that requires detecting if the executing user account is a domain admin. I do this by getting the current user and checking if they are in the Domain Admins security group.

#Get current user
$CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name | Out-String
$CurrentUser = $CurrentUser -replace 'DOMAIN\\' 

#Get list of Domain Admins members
$DomainAdmins = Get-ADGroupMember -Identity "Domain Admins" -Recursive | Select -ExpandProperty SamAccountName | Out-String

#Relevant condition
If ($DomainAdmins -like ($CurrentUser)) {
     Write-Output "You're a domain admin." #example
}
Else {
     Write-Output "You're not a domain admin."
}

Without fail, this script always runs the Else code when run from our domain controller using a domain administrator account.

I have also tried using -contains and .contains() with the exact same results. I've verified that the $CurrentUser value represents the current user accurately and that $DomainAdmins lists out the expected list of users.

I can also do this:

if ($DomainAdmins -contains ("USERNAME")) {Write-host "true"}

Where USERNAME is the current user typed out directly (case-correct or not) and it correctly returns true when that user is a member of the group.


Solution

  • Try with this:

    $userSID = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
    
    $DomainAdmins = Get-ADGroupMember -Identity "Domain Admins" -Recursive
    
    if($DomainAdmins.SID.Contains($userSID))
    {
         Write-Output "You're a domain admin."
    }
    ...
    
    # OR 
    
    if($userSID -in $DomainAdmins.SID)
    {
         Write-Output "You're a domain admin."
    }
    ...
    
    # OR
    
    if($DomainAdmins.SID -contains $userSID)
    {
        Write-Output "You're a domain admin."
    }
    

    The Out-String on Get-ADGroupMember is converting your array into a string which is why you can't use it as comparison:

    PS /> @(
        'one'
        'two'
        'three'
    ) -contains 'one'
    True
    
    PS /> (@(
        'one'
        'two'
        'three'
    ) | Out-String) -contains 'one'
    False
    

    An alternative, instead of using Get-ADGroupMember:

    $userSID = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
    
    $domainAdminsDN = (Get-ADGroup -Identity "Domain Admins").DistinguishedName
    $recursiveMembers = Get-ADUser -LDAPFilter "(memberOf:1.2.840.113556.1.4.1941:=$domainAdminsDN)"
    
    if($recursiveMembers.SID.Contains($userSID))
    {
        Write-Output "You're a domain admin."
    }
    ...
    ...