Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help with Getting SID for all members of a local Group (VBScript)

Status
Not open for further replies.

bobcrane

MIS
Sep 12, 2003
17
US
I need to get a list of all members of the local Administrators group on all servers in our environment. I then need to take that list and get the SID for each of those values.

These groups can contain local and domain accounts as well as local and foreign (trusted) domain groups (any combination).

I mashed some scripts together (below). Basically it checks for the "Administrators" group then parses through the list giving me the SID of the group members that are also groups.

My problem is this: the objUser variable returns the group name with no domain or server info. So when my WMI call goes out it finds anything by that particular name on any server or domain and returns the SID info for all of them.

Example: If a member is "domain1\domain admins" my script tells WMI to return the SID of anyone it finds named "Domain admins." The result in my case is 16 different SID's from 16 different domains.

Two questions:
1. How do I include domain information? I thought of the objWMIService.get but wasn't sure if that would be better or worse.

2. Is there a much better way to get the desired results?

Thanks!

-----------------
strComputer = InputBox("Server Name:)
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colGroups = GetObject("WinNT://" & strComputer & "")
colGroups.Filter = Array("group")
For Each objGroup In colGroups
If objGroup.Name = 'Administrators"
Then
For Each objUser in objGroup.Members
Set colItems = objWMIService.ExecQuery _
("Select * from Win32_Group Where Name = '" & objUser & "'")
For Each objitem in Colitems
Wscript.Echo "SID: " & objItem.SID
Next
Next
end if
Next

 
[0] If you want to do thing with administrators group, bind directly to it. Enumerate then screen it with name is an expensive operation.

[1] The domain info can only be "discovered" or exposed through objuser's adspath property. This answer your question. But the problems of your script are much more than that.

[2] You bind objwmiservice to a single strComputer. Whereas as you've noted the name property does not expose the domain of the domain account, and the domain is varying as said. That is definitely unsatisfactory. Hence, the do it properly, you've to bind to the domain server for the wmi service and query the sid therefrom.

[3] There is no reason why the members be groups a priori. Rather than binding to win32_group and find none return to discover the fact the "member" is not a group object, you should screen it out rightaway before trying the expensive process of binding wmi service to it.

[4] Combining the above, the script can/should look better like this. I do not keep your wrong script lines or lines that should be commented out .
[tt]
strComputer = InputBox("Server Name:)
Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators, group")
For Each objMember in objGroup.Members
if strcomp(objMember.class, "Group", 1)=0 then
a=split(objUser.adspath,"/")
sdom=a(2)
sname=a(3)
Set objWMIService=GetObject("winmgmts://" & sdom & "/root/cimv2")
Set colItems = objWMIService.ExecQuery ("Select * from Win32_Group Where Name = '" & sname & "'")
For Each objitem in Colitems
Wscript.Echo "SID: " & objItem.SID
Next
set ColItems=nothing
set objWMIService=nothing
end if
Next
set objGroup=nothing
[/tt]
[5] If you want to get only the standardized string notation for SID, even you or we don't have ConvertSIDToStringSid function at the scripting's disposal. But, by a grand detour through making out hex string etc via the intermediate of adodb.stream... you can still get the standardized string notation. Through winmgmts: to eventually obtain the standardized format is fine amid more expensive.

[6] All in all, with that kind of anticipated cross-domain even cross-forest querying, you should have appropriate security consideration before doing that, otherwise, it would be frustrations ahead. Apparent free access as shown in [4] wouldn't normally be given.
 
Thanks. I will give it a shot when I get in. A bg difference from my resource hogging mess.

As to your comment in [6] - When this is complete, it will be tied to a service account and I'll probably use impersonate to use an account with just enough rights.

One other question: Any idea how much more efficient it would be to use a "Select SID" instead of a "Select *" statement?

Thanks again,

Bob
 
The more restrict the better: that is a common norm.
 
Also, bear in mind that I leave out quite a bit to make out a more robust script. Such as if Administrators group is renamed or deleted, you can wrap the main part with "if not (objGroup is nothing) then... end if", just an example. Those things you can always improve with no end after the main functionality got layout correctly.
 
amendment:
I forgot to edit this line when I change the objUser to objMember for more clarity.
>[self]>a=split(objUser.adspath,"/")
should be read
[tt]a=split(objMember.adspath,"/")[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top