Query Local Administrators with WMI

I have a quick post today on using WMI to list members of the local administrators group. It is very simple to get the group itself with the Win32_Group class.

PS S:\> get-wmiobject win32_group -filter "name='Administrators'"

Caption Domain Name SID
------- ------ ---- ---
SERENITY\Adminis... SERENITY Administrators S-1-5-32-544

But the class doesn’t have any methods or properties for returning members. However, WMI does allow for this cool thing called “Associators Of”. Basically we ask WMI, “Find everything associated or related to this object”. One quick way to do this is with the GetRelated() method.

PS S:\> $group=get-wmiobject win32_group -filter "name='Administrators'"
PS S:\> $group.GetRelated()

By default this will probably return more information than what you need. However, if you know you want to limit results to a single class you can do something like this:

PS S:\> $group=get-wmiobject win32_group -filter "name='Administrators'"
PS S:\> $group.GetRelated("win32_useraccount")

AccountType : 512
Caption : SERENITY\Administrator
SID : S-1-5-21-2858895768-3673612314-3109562570-500
FullName :
Name : Administrator

AccountType : 512
Caption : SERENITY\Jeff
SID : S-1-5-21-2858895768-3673612314-3109562570-1000
FullName :
Name : Jeff

AccountType : 512
Caption : SERENITY\Backup
SID : S-1-5-21-2858895768-3673612314-3109562570-1010
FullName :
Name : Backup

That’s pretty easy and fast. Unfortunately in this scenario, the group might also have other groups as a member which is a different class and I couldn’t find a reasonable syntax with GetRelated() to handle multiple classes. So instead we’ll go back to native WMI approach and use an Associators Of query.

This type of query must be follow a specific format. The best way is to use WBEMTest to find your object, then click on the Assopciators button. Your query syntax will be in the top of the query dialog box. This default query will return everything, but you can add additional filtering. Check out http://msdn.microsoft.com/en-us/library/windows/desktop/aa384793(v=vs.85).aspx to learn more. In this situation, this query will return both users and groups.

$query="Associators of {Win32_Group.Domain='$computer',Name='Administrators'} where Role=GroupComponent"

Here’s one way I might use it:

PS S:\> get-wmiobject -query $query -ComputerName $computer | Select Name,Caption,__CLASS

Name Caption __CLASS
---- ------- -------
Administrator SERENITY\Administrator Win32_UserAccount
Jeff SERENITY\Jeff Win32_UserAccount
Backup SERENITY\Backup Win32_UserAccount
Help Desk SERENITY\Help Desk Win32_Group

I might even refine it a bit:

PS S:\> get-wmiobject -query $query -computer $computer |
>> Select @{Name="Members";Expression={$_.Caption}},
>> @{Name="Type";Expression={([regex]"User|Group").matches($_.__CLASS)[0].Value}},
>> @{Name="Computername";Expression={$_.__SERVER}}

Members Type Computername
------- ---- ------------
SERENITY\Administrator User SERENITY

It doesn’t take much more effort to turn this into a function, but I’ll leave that fun to you.