VBS scripting help

Associate
Joined
18 Oct 2002
Posts
2,149
Location
Cambridge
I've been tasked with finding which users on my company's local network have local admin rights on their PCs. Unfortunately the way these rights have been assigned (via a Domain Group and Restricted Groups) means that gathering the information is more tricky than just extracting it frrom AD.

I've established that it can be found via membership of the BUILTIN\Administrators group, but also that this cannot be checked remotely or via WMI, as it doesn't report the membership of the BUILTIN\Administrator group correctly.

I've managed to write a batch file which parses the results of a gpresult and writes to a CSV, which could be deployed via logon script, but have been trying to see if the same could be achieved more elegantly via VBS. Here is the script:

Code:
Option Explicit
Const HKEY_LOCAL_MACHINE = &H80000002
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7

Dim strComputer, objRegistryGetSID, objRegistryIsLocalAdmin
Dim strSIDKeyPath, arrSIDSubKeys, objSID

'set to local computer
strComputer = "."

'Regular Expression to find User SIDs and exclude default ones
Dim MyRegExp, targetString, colMatch1, objMatch1
Set MyRegExp = New RegExp
With MyRegExp
  .Pattern = "S-1-5-21"
  .Global = True
  .IgnoreCase = True
End With

'set Registry queries 
Set objRegistryGetSID=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
Set objRegistryIsLocalAdmin=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 
'query to get user SIDs from Registry 
strSIDKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy"
objRegistryGetSID.EnumKey HKEY_LOCAL_MACHINE, strSIDKeyPath, arrSIDSubKeys
 
 'Cycle through array produced by query above to enumerate userr SIDs
For Each objSID In arrSIDSubKeys
	targetString = objSID
	Set colMatch1 = MyRegExp.Execute(targetString)

	'Enumerate user SIDS for stage 2
	For each objMatch1 in colMatch1
		Dim strUserKeyPath, arrEntryNames, arrValueTypes
		strUserKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\" & objSID & "\Group Membership"
		'Echo full string (for testing purposes)
		Wscript.Echo strUserKeyPath
		
		'Query to list all groups that user is a member of
		objRegistryIsLocalAdmin.EnumValues HKEY_LOCAL_MACHINE, strUserKeyPath, arrEntryNames, arrValueTypes
		
		'Check that viariable is an array
		If Not IsArray(arrEntryNames) Then
			Wscript.Echo "No array returned1"
		End If

		'Loop through array to find user SIDs that are members of the BUILTIN\Administrators local group and report back if they are.
 		For i=0 To UBound(arrEntryNames)
			objRegistryIsLocalAdmin.GetStringValue HKEY_LOCAL_MACHINE, strUserKeyPath, arrEntryNames(i),strValue
			If strValue = "S-1-5-32-544" then
				Wscript.Echo "IsLocalAdmin"
			End If
		Next	
	Next	
Next

The script loops through the registry and correctly harvests the USER SIDs, but the second part of the script, where it supposedly creates and then searches through an array of the groups that the user is a member of does not work, reporting a UBound type mismatch error (the array check also reports that it is not one). Now, that part of the script works fine in a separate VBS if I feed the SID and registry key path to it manually, so I'm confused as to why it's suddenly not working?
 
Last edited:
Correct me if i'm wrong but if your machines are part of a domain and you use Restricted groups to set membership of the BUILTIN\Administrators group, this policy will remove anyone not set in the policy from the local admin group. Everyone except the computers own BUILTIN admin account anyway.

EDIT - yep seems i am right:

http://technet.microsoft.com/en-us/library/cc785631(WS.10).aspx

This security setting allows an administrator to define two properties for security-sensitive groups ("restricted" groups).

The two properties are Members and Member Of. The Members list defines who belongs and who does not belong to the restricted group. A group can be a member of groups other than those listed in the Member Of section. The Member Of section simply ensures that the restricted group is added to the groups listed in Member Of. It does not remove the group from other groups of which it is a member.

When a Restricted Groups Policy is enforced, any current member of a restricted group that is not on the Members list is removed. Any user on the Members list who is not currently a member of the restricted group is added.

This seems you just need to see which groups/users you have specified in the policy surely?
 
Last edited:
You're no doubt correct, unfortunately being a lower-end-of-the-scale sysadmin in my current job I don't have the rights to view the security configuration on the servers & therefore have to do it from a client-side perspective (annoying I know!)
 
I'm sorry but it seems they are making you waste your time!

Tell you what look at your own Admins group on your client and see who's in it :D

This will likely be the same across every machine connected to the domain, the whole point of Restricted Groups is just that, to restrict the memberships to only those specified.
 
Point taken & I will certainly feed that back... However I'm still lumbered with the job and there 'may' be isolated cases of users being manually added as local administrators (via control panel) which this would not pick up.

As an exercise in scripting & learning more about vbs then, can it be done? I'm guessing that the two arrays 'arrEntryNames, arrValueTypes' are not actually being returned as arrays by the second query?
 
In my experience even if you add someone back into the admin group, i.e one admin goes and adds another non admin to the admin group, as soon you log back in again and group policies update, it will again remove the users who are not explicitly listed in the policy :)
 
Back
Top Bottom