1
votes

I know how to fetch a list of local administrators on a remote machine via WMI:

wmic /Node:"ComputerName" path win32_groupuser where (groupcomponent="win32_group.name=\"administrators\",domain=\"Computername\"")

This will return users and groups:

GroupComponent PartComponent win32_group.domain="Computername",name="administrators" \\Computername\root\cimv2:Win32_UserAccount.Domain="Computername",Name="Administrator" win32_group.domain="Computername",name="administrators" \\Computername\root\cimv2:Win32_Group.Domain="MYDOMAIN",Name="Domain Admins" win32_group.domain="Computername",name="administrators" \\Computername\root\cimv2:Win32_Group.Domain="MYDOMAIN",Name="SomeOtherGroup" win32_group.domain="Computername",name="administrators" \\Computername\root\cimv2:Win32_UserAccount.Domain="MYDOMAIN",Name="MyUser"

However, if a user is a member of SomeOtherGroup above, I need to know that he is a member - and therefore a local admin. So, I need to expand (likely recursively) all group members.

Is there a WMI query that can self-join on win32_group, expanding all usernames of all groups that are local admins?

1

1 Answers

1
votes

There is ASSOCIATORS OF statement in the WMI Query Language (WQL):

The ASSOCIATORS OF statement retrieves all instances that are associated with a particular source instance. The instances that are retrieved are referred to as the endpoints. Each endpoint is returned as many times as there are associations between it and the source object.

The following VBScript should do the job:

option explicit

Function wmiGroupMembers( sGroupName, intLevel)
  Dim colSubGroups, colSubGroup, sQuery

  sQuery = "Associators of {win32_group.domain=""" & sDomainName & _
                                      """,name=""" & sGroupName & """} " _
        & "Where ResultRole = PartComponent"

  Set colSubGroups = objWMIService.ExecQuery( sQuery )
  For Each colSubGroup in colSubGroups
    If LCase( colSubGroup.Path_.Class) = "win32_group" Then
      wmiGroupMembers colSubGroup.Name, intLevel + 1
    End If 
    sResult = sResult & vbNewLine & intLevel _
                          & vbTab & sGroupName _
                          & vbTab & colSubGroup.Domain _
                          & vbTab & colSubGroup.Name
  Next
End Function

Dim sResult, wshNetwork, sComputerName, sDomainName, objWMIService
sResult = ""
Set wshNetwork    = WScript.CreateObject( "WScript.Network" )
    sComputerName = wshNetwork.ComputerName
    sDomainName   = UCase( wshNetwork.UserDomain)
Set objWMIService = GetObject("winmgmts:\\" & sComputerName & "\root\cimv2")

wmiGroupMembers "administrators", 0

Wscript.Echo sResult

Note that although there is a wmic equivalent (see ASSOC verb), it's usage could be a tough problem as all output from any cmd utility is text (i.e. not objects) and must be parsed using for loop command.