• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2815
  • Last Modified:

How to list users of a Administrators group in Powershell

I have a requirement to find whether a user is member of Local Administrators group of a computer or not. This is a domain user on domain D1. It is also member of a group "Domain Admins" on AD. Now i am using the below code to find out if he is in "Local Administrators" group on Computer C1. iam using following script:
# $strComputer = "C1"
# $computer = [ADSI]("WinNT://" + $strComputer + ",computer")
# $Group = $computer.psbase.children.find("Administrators")
# $members= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
#  
# foreach($user in $members)
# {
#     Write-Host $user
#     $a = $strComputer + "!" + $user.ToString()
# }

This code is fine but it not giving the user as a member but giving "Domain Admins" as member.

Is there a way to find out if the user is member of a group on AD and that group is member of Administrators group.
0
vickytaurus
Asked:
vickytaurus
  • 4
  • 3
  • 2
  • +1
1 Solution
 
MaSTeRiToCommented:
You need to use powershell?
I use "ifmember.exe" for that.
You can find it in the resource kit

http://www.microsoft.com/downloads/details.aspx?FamilyID=07C2F6D7-815E-4FA0-9043-4E4635CCD417&displaylang=en&displaylang=en

 
0
 
vickytaurusAuthor Commented:
I cannot use any exe, i have to write a powershell script.
Thanks.
0
 
soostibiCommented:
If you have Quest's Quest.ActiveRoles.ADManagement snapin, then maybe this is yours:
$strComputer = "soostpc"
$strUser = "iqjb\iqjbadmin"

$usertofind = Get-QADUser $struser
$computer = [ADSI]("WinNT://" + $strComputer + ",computer") 
$Group = $computer.psbase.children.find("Administrators") 
$members= $Group.psbase.invoke("Members") | %{$_.GetType().InvokeMember("ADSPath", 'GetProperty', $null, $_, $null)} 
  
$members = $members | Select-Object -Property @{n="domain"; e={($_ -split "/+")[-2]}}, 
                @{n="user"; e={($_ -split "/+")[-1]}} , @{n="fullname"; e={"$(($_ -split '/+')[-2])\$(($_ -split '/+')[-1])"}}
$allusermembers = $members | ?{$_.domain -ne $strcomputer} | %{Get-QADObject $_.fullname} | %{
        if($_.type -eq "group"){ Get-QADGroupMember $_}
        else{$_}
    }
if(($allusermembers | %{$_.dn}) -contains $usertofind.dn) {"$struser is member of the local Administrators group"}
else {"$struser is NOT member of the local Administrators group"}

Open in new window

0
Network Scalability - Handle Complex Environments

Monitor your entire network from a single platform. Free 30 Day Trial Now!

 
Chris DentPowerShell DeveloperCommented:

To test that you'd have to expand all the groups listed in the local admin group.

Starting from the beginning, you'd need the classes for the members. Then you'd have to take each group and see if the user was a member.

There's a complication, do you want it to handle nested group membership?

Chris
$Computer = "C1"

#
# Get the members of the local admin group
#

$AdminGroup = [ADSI]"WinNT://$strComputer/Administrators"
$Members = $AdminGroup.Members() | Select-Object `
  @{n='Name';e={ $_.GetType().InvokeMember('Name', 'GetProperty', $Null, $_, $Null) }},
  @{n='ADSPath';e={ $_.GetType().InvokeMember('ADSPath', 'GetProperty', $Null, $_, $Null) }},
  @{n='Class';e={ $_.GetType().InvokeMember('class', 'GetProperty', $Null, $_, $Null) }},
  @{n='Type';e={ "Direct" }}

#
# Expand groups (one level only)
#

$Members | ForEach-Object {
  If ($_.Class -eq "Group") {
    $Group = [ADSI]$_.ADSPath
    $Group.Members() | Select-Object `
      @{n='Name';e={ $_.GetType().InvokeMember('Name', 'GetProperty', $Null, $_, $Null) }},
      @{n='ADSPath';e={ $_.GetType().InvokeMember('ADSPath', 'GetProperty', $Null, $_, $Null) }},
      @{n='Class';e={ $_.GetType().InvokeMember('class', 'GetProperty', $Null, $_, $Null) }},
      @{n='Type';e={ "Indirect" }}
  } Else {
    $_
  }
}

Open in new window

0
 
soostibiCommented:
If you have nested groups, then this code should be further developed... So if the user is in a group and this group is inside the Domain Admins group... Tell me is this is your case.
There are other options if you have Windows Server 2008 R2 or the Management Gataway installes, in these case we can use the Microsoft's AD cmdlets.
0
 
Chris DentPowerShell DeveloperCommented:

Yours is easy soostibi, add -Indirect to Get-QADGroupMember :)

Alas mine isn't so easy.

Chris
0
 
vickytaurusAuthor Commented:
I am trying to use solution byChris, modifying to call recursively. I cannot use Get-QADUser, can only use basic Powershell.
0
 
Chris DentPowerShell DeveloperCommented:

I would avoid recursion, instead aim for the LDAP operator to match down a chain. One moment, I'll pop another example up.

Chris
0
 
Chris DentPowerShell DeveloperCommented:

Like this :)

The LDAP filter I'm using is documented here:

http://msdn.microsoft.com/en-us/library/aa746475%28VS.85%29.aspx

Lets you trivially pull the members down nested chains without having to worry about loops.

Chris
$Computer = "C1"

Function Get-GroupMember {
  Param(
    [String]$GroupName
  )

  # Get the group DN
  $Group = (New-Object DirectoryServices.DirectorySearcher("sAMAccountName=$GroupName")).FindOne()

  # Build the filter
  $LdapFilter = "(memberOf:1.2.840.113556.1.4.1941:=$($Group.Properties["distinguishedname"][0]))"

  # Get the group members
  (New-Object DirectoryServices.DirectorySearcher($LdapFilter)).FindAll() | Select-Object `
    @{n='Name';e={ $_.Properties["name"][0] }},
    @{n='ADSPath';e={ $_.Properties["adspath"][0] }},
    @{n='Class';e={ $Class = [Array]($_.Properties["objectclass"]); $Class[-1] }},
    @{n='Type';e={ "Indirect" }}
}

#
# Get the members of the local admin group
#

$AdminGroup = [ADSI]"WinNT://$strComputer/Administrators"
$Members = $AdminGroup.Members() | Select-Object `
  @{n='Name';e={ $_.GetType().InvokeMember('Name', 'GetProperty', $Null, $_, $Null) }},
  @{n='ADSPath';e={ $_.GetType().InvokeMember('ADSPath', 'GetProperty', $Null, $_, $Null) }},
  @{n='Class';e={ $_.GetType().InvokeMember('class', 'GetProperty', $Null, $_, $Null) }},
  @{n='Type';e={ "Direct" }}

#
# Expand groups (one level only)
#

$Members | ForEach-Object {
  If ($_.Class -eq "Group") {
    Get-GroupMember $_.Name
  } Else {
    $_
  }
}

Open in new window

0
 
vickytaurusAuthor Commented:
Thanks Chris, i will use the approach and code given by you. It seems to solve the problem.
Thanks
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now