Need help with powershell ADSI query that loops to find members of an AD group

JP Luna 21 Reputation points
2022-03-04T22:19:26.807+00:00

I have a PowerShell script below where I'm able to get the group members of an AD group. It returns the columns name, SchemaClassName and UserAccountControl. What I'm trying to do now is I want to add a switch/if statement that replaces the UserAccountControl results from bit to either "True" or "False" string. I have tried multiple iterations and have been unsuccessful at it. I am using ADSI because the environment that I am using it for does not allow the get commands. If anyone could point me in the right direction would be greatly appreciated!

Good code
$Group = [ADSI]"LDAP://cn=Groupname,OU=Groups,OU=Users,OU=xxxx,dc=xxx,dc=xxx,dc=xxx"
$Members = $Group.Member | ForEach-Object {[ADSI]"LDAP://$"}
$Members | Select-Object | Select @{N='Members' ;e={$
.name}}, @{N='Type' ;e={$.SchemaClassName}}, @{N='Enabled' ;e={$.UserAccountControl}}

Broken code
$Group = [ADSI]"LDAP://cn=Groupname,OU=Groups,OU=Users,OU=xxxx,dc=xxx,dc=xxx,dc=xxx"
$Members = $Group.Member | ForEach-Object {[ADSI]"LDAP://$"}
$Members | Select-Object | Select @{N='Members' ;e={$
.name}}, @{N='Type' ;e={$.SchemaClassName}}, @{N='Enabled' ;e={$.UserAccountControl}} $Enabled -eq '512' if ($Enabled -eq "512"){"True"} elseif ($Enabled -eq 514){"False"} elseif ($Enabled -eq 66048){"True"} elseif ($Enabled -eq 66050){"False"} else {""}

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,405 questions
0 comments No comments
{count} votes

Accepted answer
  1. Rich Matheisen 45,111 Reputation points
    2022-03-09T02:46:42.523+00:00

    I forgot . . . it's been so long since I've used ADSI. There's a missing subscript in your script! See the last calculated property in the last Select-Object.

    $Group = [ADSI]"LDAP://cn=Groupname,OU=Groups,OU=Users,OU=xxxx,dc=xxx,dc=xxx,dc=xxx"
    $Members = $Group.Member | 
        ForEach-Object {[ADSI]"LDAP://$_"}
    $Members |  
        Select-Object @{N='Members' ;e={$_.name}}, @{N='Type' ;e={$_.SchemaClassName}}, @{N='Enabled' ;e={($_.UserAccountControl[0] -band 2) -eq 2}}
    

    The result is:

    Members              Type Enabled
    -------              ---- -------
    Melvin McPhucknuckle user    True
    XXX                  user   False
    

3 additional answers

Sort by: Most helpful
  1. Rich Matheisen 45,111 Reputation points
    2022-03-05T02:57:58.583+00:00

    I think this is what you were aiming for, but it's difficult to know because the "Select" line is pretty wonky!

    # 512   = normal account
    # 514   = normal account, account disabled?
    # 66048 = normal account, don't expire password 
    # 66050 = normal account, account disabled, don't expire password
    
    Get-ADGroupMember -Identity Groupname |
        ForEach-Object{
            $u = Get-ADUser -Identity $_.distinguishedname
            [PSCustomObject]@{
                Members         = $u.Name
                Type            = $u.objectclass
                Enabled         = $u.Enabled
                PasswordExpires = $u.PasswordNeverExpires
            }
        }
    

    When you post code, please use the "Code Sample" editor (it's the 5th icon from the left on the Format Bar (the icon has the graphic "101 010").

    If you post code using the "normal" editor the code gets mangled (notice in your post that the underbar characters disappeared!). It also makes separating code from commentary difficult.


  2. JP Luna 21 Reputation points
    2022-03-08T19:20:09.877+00:00

    @Rich Matheisen
    Here's the script that I have currently.

            Function DecodeUserAccountControl ([int]$UAC)  
            {  
            $UACPropertyFlags = @(  
            "SCRIPT",  
            "ACCOUNTDISABLE",  
            "RESERVED",  
            "HOMEDIR_REQUIRED",  
            "LOCKOUT",  
            "PASSWD_NOTREQD",  
            "PASSWD_CANT_CHANGE",  
            "ENCRYPTED_TEXT_PWD_ALLOWED",  
            "TEMP_DUPLICATE_ACCOUNT",  
            "NORMAL_ACCOUNT",  
            "RESERVED",  
            "INTERDOMAIN_TRUST_ACCOUNT",  
            "WORKSTATION_TRUST_ACCOUNT",  
            "SERVER_TRUST_ACCOUNT",  
            "RESERVED",  
            "RESERVED",  
            "DONT_EXPIRE_PASSWORD",  
            "MNS_LOGON_ACCOUNT",  
            "SMARTCARD_REQUIRED",  
            "TRUSTED_FOR_DELEGATION",  
            "NOT_DELEGATED",  
            "USE_DES_KEY_ONLY",  
            "DONT_REQ_PREAUTH",  
            "PASSWORD_EXPIRED",  
            "TRUSTED_TO_AUTH_FOR_DELEGATION",  
            "RESERVED",  
            "PARTIAL_SECRETS_ACCOUNT",  
            "RESERVED"  
            "RESERVED"  
            "RESERVED"  
            "RESERVED"  
            "RESERVED"  
            )  
            return (0..($UACPropertyFlags.Length) | ?{$UAC -bAnd [math]::Pow(2,$_)} | %{$UACPropertyFlags[$_]}) -join ” | ”  
            }  
              
              
            $Group = [ADSI]"LDAP://cn=xxx,OU=xxx,OU=xxx,OU=xxx,dc=xxx,dc=xxx,dc=xxx"  
            $Members = $Group.Member | ForEach-Object {[ADSI]"LDAP://$_"}  
            $Members | Select-Object | Select @{N='Members' ;e={$_.name}}, @{N='Type' ;e={$_.SchemaClassName}},@{N='Enabled' ;e={DecodeUserAccountControl($_.userAccountControl)}}   
              
              
          
          
    
      
    
    0 comments No comments

  3. Rich Matheisen 45,111 Reputation points
    2022-03-08T22:41:13.913+00:00

    In order to get the useraccountcontrol property the script must be run "as administrator".

    Runing the script simple logged in as an administrator account isn't enough. You must run the script in an elevated session.

    0 comments No comments