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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

IsUserAdmin Function

Status
Not open for further replies.

DJX995

IS-IT--Management
Jan 12, 2009
20
US
I'm tring to work on this function but I'm getting a syntax error (0x80041002). Here is what I pieced together so far:

Function IsUserAdmin(strUser)
Set objWMI = GetObject("WinMgmts:\\" & strComputerName & "\root\cimv2")

For Each objItem In objWMI.ExecQuery("ASSOCIATORS OF {Win32_Group.Domain='BUILTIN',Name='Administrators'} Where AssocClass=Win32_GroupUser")
On Error Resume Next
If InStr(1,objItem.Caption,strUser,vbTextCompare) Then
IsUserAdmin = True
End If
Next

Set objWMI = Nothing
End Function

I get the syntax error at the "For" statement.
Any suggestions?

 
have you set a value for strComputerName elsewhere?

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
[0] The associator query is defective in the sense that the Builtin may pose problem of support. It should be replaced by the local computer name (the server name). In some non-associator query, it is fine with "BUILTIN", but not associator query in this particular instance.

[0.1] Further querying win32_groupuser was recognized by ms, back in time, as not optimized and can take considerable length of time for complex domain structure. But that is another matter and could be in the past for system later than win2k.

[0.2] Also, you should also restrict the return set to win32_useraccount to make theoretically better sense, though it may not related to the non-optimization issue in the past.

[1] This is what should be scripted in the big issue, the rest is just detail.
[tt]
Function IsUserAdmin(strUser)
dim ssql,servername,obj,cobjs,objWMI
[blue]IsUserAdmin=false[/blue]

Set objWMI = GetObject("WinMgmts:\\" & strComputerName & "\root\cimv2")

ssql="select name from win32_computersystem"
set cobjs=objWMI.execquery(ssql)
for each obj in cobjs
servername=obj.name
exit for
next
set cobjs=nothing

'[blue]exact separator and whitespace within {}
ssql="ASSOCIATORS OF {Win32_Group.Domain='" & servername & "',Name='Administrators'} Where AssocClass=Win32_GroupUser ResultClass=Win32_UserAccount"[/blue]
set cobjs=objWMI.ExecQuery(ssql)
[green]wscript.sleep 2000 'ad-hoc version, may no longer needed[/green]
for each obj in cobjs
If [blue]strcomp(obj.Name,strUser,vbTextCompare)=0[/blue] Then
IsUserAdmin = True
[blue]exit for[/blue]
End If
next
set cobjs=nothing
Set objWMI = Nothing
End Function[/tt]

[2] There are non-associator queries alternative that can be use querying directly win32_groupuser with groupcomponent using something similar to the first posting (and now the BUILTIN is supported just fine). But I just focus on the question in the form as it is asked.
 
An easier way to check is to use the WinNT provider.

Code:
'==========================================================================
'
' NAME: CheckIfUserIsLocalAdmin.vbs
'
' AUTHOR: Mark D. MacLachlan , The Spider's Parlor
' URL   : [URL unfurl="true"]http://www.thespidersparlor.com[/URL]    
' COPYRIGHT (C) 2009 All rights reserved
' DATE  : 5/24/2009
'
' COMMENT: Reports if a user is a member of the local admins group for a 
'          given computer.
'
'
'    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
'    ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
'    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
'    PARTICULAR PURPOSE.
'
'    IN NO EVENT SHALL THE SPIDER'S PARLOR AND/OR ITS RESPECTIVE SUPPLIERS 
'    BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
'    DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
'    WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
'    ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
'    OF THIS CODE OR INFORMATION.
'==========================================================================


strUser = InputBox("Enter Login to Check For Admin Status","Admin to Check ")
strComputer = InputBox("Enter Computer to Connect To","Computer to Check ")
Result = AdminCheck(strUser,strComputer)
If Result = True Then
	WScript.Echo strUser & " is a member of the local admins group on " & strComputer & "."
Else
	WScript.Echo strUser & " is NOT a member of the local admins group on " & strComputer & "." 
End If

Function AdminCheck(strUser, strComputer)
	Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators,group")

    For Each objUser In objGroup.Members
        If objUser.Name = strUser Then
        	AdminCheck = True
        End If
    Next
	Set objGroup = Nothing
End Function

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
Thanks guys,
I'll give "tsuji"'s a try when I have time and let you know.

The reason I can't just do a simple check like "markdmac" suggested is becuase the user I'm tring to check is a member of a domain group that is inside the local admins group.

That's why I was going to try the WMI method (not sure if it will detect it in my case but I'm going to give it a try).

 
No luck guys...Even the WMI method still does not detect the user as admin.

Like I said before, the user I'm tring to check is a member of a a domain group that is a member of the local admins group on the machine.

I've tried both methods (WMI and WinNT Query)

Any one else have a suggestion?

Thanks.

 
So why don't you detect if the group is present since you know the user is a member of said group?

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
I guess that would solve the problem but it's not the ideal solution.

I really wanted it to be more universal...so that I would be able to deploy this function in different environments without having to worry about the actual names.

 
Why would it not be universal? Enter the group name instead of the user name in the code I provided and it will work without modification.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
I think I'm missing something here...

Could you please post an example?

The way I understand it (I believe this is wrong) is that I have to hard code the group I want to check for? If that's true then it's not universal.

I understand checking a user in a group because the user name is a var but user groups are not vars so this is why I'm confused when you say it is indeed, universal.

Sorry if I'm way off...

Thanks.

 
I already posted the code you need. You need to read above and give the code a try. My code PROMPTS for the user name to check. Just enter the group name instead.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
I see, okay well...not very usefull since I'm tring to script an installer (don't want the end user to have to figure out all the groups he is in) but okay.

I'm tring to do this function internally without user intervention.

I guess what I really need then is some way of enumerating all the groups the user is a member (Domain groups) and then checking those againsts the local admin group.

Then, ultimately, I could probaly nest the two sides of it:
Check the user name against the local admin then, if that fails, check his groups against the local admin.

Think that would work?
Any help on accomplishing this?

 
Can you publish or run the script via AD? If so the user need not be a member of the local admins group.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
You might also like to check out:
I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
I see what you're getting at and I guess we could but it would be a mess. This needs to be installed on specific machines (I don't get to choose) for a few days then it has to be taken off untill next year when we do it again.

We would really like to have the ability to install at will.
Probaly not a bad idea if it wasn't something so dynamic, nice thinking.

 
Create a list of computers to run it on. Execute remotely from an admin workstation.

faq329-4871

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
>Like I said before, the user I'm tring to check is a member of a a domain group that is a member of the local admins group on the machine.
That is not announced in the orignal post.

What about the for each statement? Does it resolve the problem posted in the original post? If you want progress on the problem, state clear what is resolved and what is the new problem.

Pass the domainname\groupname to the function. What is the outcome?

Otherwise, I am not somebody else anyway.
 
Okay, to recap here:
Nothing so far has worked the way I originally wanted to.
I've done some searching around and can't really peice together what I need to do.
Starting from scratch, here is what I would like to do:

Function IsUserAdmin(strUser)
IsUserAdmin = False
Set objAdminGroup = GetObject("WinNT://" & strComputerName & "/Administrators,group")

For Each objAdminMember In objAdminGroup.Members
If objAdminMember.Name = strUser Then
IsUserAdmin = True
Else
' Check Domain Groups User Is A Member Of Against Local Admin Group
End If
Next

Set objAdminGroup = Nothing
End Function

I just need the part where is checks all the users domain groups against the local admin group. Not a common operation, most people just want to check one specific group but I need to check all of them.

 
I was able to figure it out.

This is the main function:
Code:
	Function IsUserAdmin(strUser)
		IsUserAdmin = False

		Set objAdminGroup = GetObject("WinNT://" & strComputerName & "/Administrators,group")

		For Each objAdminMember In objAdminGroup.Members
			If objAdminMember.Name = strUser Then
				IsUserAdmin = True
				Exit For
			Else
				For Each strGroup in strUserMemberOf
					arrGroup = Split(Mid(strGroup, 4, 330), "," )
					If objAdminMember.Name = arrGroup(0) Then
						IsUserAdmin = True
						Exit For
					End If
				Next
			End If
		Next

		Set objAdminGroup = Nothing
	End Function
...Which requires this function:
Code:
	Function SearchDistinguishedName(ByVal vSAN)
		Set objRootDSE = GetObject("LDAP://rootDSE")
		Set objConnection = CreateObject("ADODB.Connection")
			objConnection.Open "Provider=ADsDSOObject;"
		Set objCommand = CreateObject("ADODB.Command")
			objCommand.ActiveConnection = objConnection
			objCommand.CommandText = "<LDAP://" & objRootDSE.get("defaultNamingContext") & ">;(&(objectCategory=User)(samAccountName=" & vSAN & "));distinguishedName;subtree"

		Set objRecordSet = objCommand.Execute

		On Error Resume Next
			SearchDistinguishedName = objRecordSet.Fields("DistinguishedName")
		On Error GoTo 0

		objConnection.Close

		Set objRecordSet = Nothing
		Set objCommand = Nothing
		Set objConnection = Nothing
		Set objRootDSE = Nothing
	End Function
...And looks at these variables:
Code:
	Set objWSHNetwork = CreateObject("WScript.Network")
		strUserName = objWSHNetwork.UserName

	strUserDN = SearchDistinguishedName(strUserName)
	Set objADUser = GetObject("LDAP://" & strUserDN)
		strUserMemberOf  = objADUser.GetEx("MemberOf")

It works but does anyone see any problems or performance improvements?

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top