Solved

Any script that can query a group on the root Domain and get me the results as this.

Posted on 2008-09-30
30
348 Views
Last Modified: 2012-05-05
Hi,

Any script that can query a group on the root Domain and get me the results as this. From group and all nested groups too.

Username
Groups the user is a member
If nested group the group name

So finally i have just users who are in the group and all nested groups the user may be into.

this would be helpful for me to remove all unwanted groups the user is for 1 purpose of he/she has to be in the group.

Say in many cases i have users who are in the group and in many nested groups for no use. By this i can remove the user from all unwanted groups .

Regards
Sharath
0
Comment
Question by:bsharath
  • 15
  • 7
  • 5
  • +1
30 Comments
 
LVL 58

Expert Comment

by:tigermatt
ID: 22608072
I can't do anything more than simple scripting to Active Directory. Is the below the sort of thing you need?

Set the domain in strDomain and group path in strGroup.

Matthew

'Domain
strDomain = "DC=domain,DC=com"
strGroup = "CN=Administrators,CN=Builtin,"
strLog = "C:\groupmembers-" & Year(Date()) & "-" & Month(date()) & "-" & Day(Date()) & "--" & Hour(Time()) & "." & Minute(time()) & "." & Second(time()) & ".log"
 
Set fso = CreateObject("Scripting.FileSystemObject")
Wscript.echo strLog
Set logobj = fso.CreateTextFile(strLog)
 
Set objGroup = Getobject("GC://" & strGroup & strDomain)
objGroup.GetInfo
 
arrMemberOf = objGroup.GetEx("member")
 
For each x in arrMemberOf
	
	Set userobj = getobject("GC://" & x)
	
	logobj.WriteLine "Object: " & x & " is a member of: "
	
	for each y in userobj.GetEx("memberof")
		logobj.writeline "-" & y
	next
	
	Set userobj = nothing
	Set y = nothing
	Set strusername = nothing
 
next

Open in new window

0
 
LVL 11

Author Comment

by:bsharath
ID: 22608223
Thanks but this does not fetch the Root Domain groups....
0
 
LVL 58

Expert Comment

by:tigermatt
ID: 22608898
I've no idea in that case. I'm not too good with ADSI scripting - can rejoinder help?
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 21

Expert Comment

by:AmazingTech
ID: 22663937
Are you querying a user and which groups and nested groups he/she belongs to?

So:

User1:
       group1
       group2
                   nestedgroup1
       group3
       group4
                  nestedgroup2

How do you want the output to look like?

Do you want to specify a user or all users in an OU?
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 22666070
Sharath, try this script, changing:

strOU = "OU=IT Users,OU=Users,OU=Civic Centre,OU=Sites,"

to another OU, or just strOU = "" for the whole domain, and

strDNSDomain = objRootDSE.Get("defaultNamingContext")

to
strDNSDomain = "DC=root,DC=domain,DC=com"

for your root domain name.

Bear in mind, if there's a circular group reference, it can get hung up....

Regards,

Rob.
If Right(LCase(WScript.FullName), 11) = "wscript.exe" Then
	Set objShell = CreateObject("WScript.Shell")
	objShell.Run "cscript """ & WScript.ScriptFullName & """", 1, False
	Set objShell = Nothing
	WScript.Quit
End If
 
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
 
 ' Search entire Active Directory domain.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
'strBase = "<LDAP://" & strDNSDomain & ">"
strOU = "OU=IT Users,OU=Users,OU=Civic Centre,OU=Sites,"
If Right(strOU, 1) <> "," Then strOU = strOU & ","
strBase = "<LDAP://" & strOU & strDNSDomain & ">"
 
strFilter = "(&(objectCategory=person)(objectClass=user))"
'strFilter = "(&(objectClass=computer)(cn=" & strComputer & "))"
 
' Comma delimited list of attribute values to retrieve.
'strAttributes = "sAMAccountName,cn"
strAttributes = "ADsPath"
 
' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
 
' Run the query.
Set adoRecordset = adoCommand.Execute
 
' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
	WScript.Echo ""
	WScript.Echo "Proccessing: " & adoRecordset.Fields("ADsPath").Value
    ' Retrieve values and display.
	Set objUser = GetObject(adoRecordset.Fields("ADsPath").Value)
 
	strResults = ""
	strGroups = ""
	
	intLevel = 0
	
	GetMemberOfNames objUser, intLevel
	
	strResults = Replace(objUser.Name, "CN=", "") & " is a member of: "
	arrGroups = Split(strGroups, VbCrLf)
	For intCount = LBound(arrGroups) To UBound(arrGroups)
		If strResults = "" Then
			strResults = arrGroups(intCount)
		Else
			strResults = strResults & VbCrLf & arrGroups(intCount)
		End If
	Next
 
	Set objUser = Nothing
 
	WScript.Echo ""
	WScript.Echo strResults
	adoRecordset.MoveNext
Loop
 
' Clean up.
adoRecordset.Close
Set adoRecordset = Nothing
 
adoConnection.Close
 
WScript.Echo "Done"
MsgBox "Done"
 
Sub GetMemberOfNames(objObjectToCheck, intLevel)
	' This function can get caught in a loop if there is a circular
	' group membership.  There is a method of using a Dictionary object
	' here: http://www.rlmueller.net/MemberOf.htm
	' which checks if the group has been used before.
	
	intLevel = intLevel + 1
	' Retrieve ALL of the user groups that a user is a member of
	On Error Resume Next
	objMemberOf = objObjectToCheck.GetEx("MemberOf")
	If Err.Number = 0 Then
		On Error GoTo 0
		For Each objGroup in objMemberOf
			strGroupName = Left(Mid(objGroup, InStr(objGroup, "CN=") + 3),InStr(Mid(objGroup, InStr(objGroup, "CN=") + 3), ",") - 1)
			If strGroups = "" Then
				strGroups = String(intLevel, ">") & strGroupName
			Else
				strGroups = strGroups & VbCrLf & String(intLevel, ">") & strGroupName
			End If
			Set objNextGroup = GetObject("LDAP://" & objGroup)
			GetMemberOfNames objNextGroup, intLevel
		Next
		intLevel = intLevel - 1
	Else
		intLevel = intLevel - 1
		Err.Clear
		On Error GoTo 0
	End If
End Sub

Open in new window

0
 
LVL 65

Expert Comment

by:RobSampson
ID: 22666074
Something like this appears to be able to get cross-domain membership as well as prevent that circular problem....
http://www.rlmueller.net/IsMember6.htm

Regards,

Rob.
0
 
LVL 11

Author Comment

by:bsharath
ID: 22666093
Hi
Yes Rob that would be better....
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 22666104
OK, so take that code from the link aboe (there's a link at the bottom of the page to get the code), and try it out....

Regards,

Rob.
0
 
LVL 11

Author Comment

by:bsharath
ID: 22666133
Ok Rob i shall get the results tommorow...
0
 
LVL 11

Author Comment

by:bsharath
ID: 22675897
Ron in this path
strOU = "OU=IT Users,OU=Users,OU=Civic Centre,OU=Sites,"
Where should i mention the group name of the root Domain?
0
 
LVL 11

Author Comment

by:bsharath
ID: 22675898
Ron in this path
strOU = "OU=IT Users,OU=Users,OU=Civic Centre,OU=Sites,"
Where should i mention the group name of the root Domain?
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 22675950
So far, there is no group name specified. This just outputs all of the group memberships for every user, including nested groups......you could search through the results file for a specific group.....

Regards,

Rob.
0
 
LVL 11

Author Comment

by:bsharath
ID: 22675995
Rob i want to query a group and get results.
So when queried have to get the users abnd any nested group details to a file if nested get the users within that nested group.
0
 
LVL 11

Author Comment

by:bsharath
ID: 22675996
Rob i want to query a group and get results.
So when queried have to get the users abnd any nested group details to a file if nested get the users within that nested group.
0
 
LVL 11

Author Comment

by:bsharath
ID: 22687642
Hi Matthew \ Rob \ AT

Just wanted to let you know my joy.

I have been blessed with a Boy baby today... :-)
0
 
LVL 21

Expert Comment

by:AmazingTech
ID: 22687799
Congratulations! Is this your first child?
0
 
LVL 11

Author Comment

by:bsharath
ID: 22687814
Thank U AT Yes my first... :-)
0
 
LVL 21

Expert Comment

by:AmazingTech
ID: 22693190
When you have time. Can you verify if this is sort of what you want? The output is not yet correct but I think it is grabbing the data you want.

Specify a group.
List group members
List nested group members

I think you want the output to be sorted by user.
Const E_ADS_PROPERTY_NOT_FOUND = &H8000500D
 
On Error Resume Next
 
Set objPrimaryGroup = GetObject _
    ("LDAP://cn=Domain Admins,ou=Groups,dc=domain,dc=com")
objPrimaryGroup.GetInfo
 
arrMembers = objPrimaryGroup.GetEx("Member")
 
If Err.Number <> E_ADS_PROPERTY_NOT_FOUND Then
    For Each strmember In arrMembers
        wscript.echo vbTab & strmember
            
        Call NestedGroup(strmember, 2)
    Next
Else
    wscript.echo vbTab & "No members."
    Err.Clear
End If
 
wscript.echo
 
Sub NestedGroup(Group, NumTabs)
    On Error Resume Next
    Set objGroup = GetObject _
        ("LDAP://" & Group)
    objGroup.GetInfo
    If LCase(objGroup.Class) = "group" Then
        PrintTabs = ""
 
        For I = 1 To NumTabs
            PrintTabs = PrintTabs + vbTab
        Next
 
        arrGroupMembers = objGroup.GetEx("member")
 
        If Err.Number <> E_ADS_PROPERTY_NOT_FOUND Then
            For Each strmember In arrGroupMembers
                wscript.echo PrintTabs & strmember
                Call NestedGroup(strmember, NumTabs + 1)
            Next
        End If
    End If
End Sub

Open in new window

0
 
LVL 65

Expert Comment

by:RobSampson
ID: 22699083
Sharath, congratulations!!!  I'm sure you will have a very enjoyable experience with your new child!

Rob.
0
 
LVL 11

Author Comment

by:bsharath
ID: 22699791
Thanks Rob....
0
 
LVL 58

Expert Comment

by:tigermatt
ID: 22700553
Sharath,

Congratulations all around from me too!!

Matthew
0
 
LVL 11

Author Comment

by:bsharath
ID: 22701916
Thanks Matthew...
0
 
LVL 11

Author Comment

by:bsharath
ID: 22709355
Yes AT this gets me the users but they reflect on the screen as popup's

Can this be got into an csv with sorting by users...
0
 
LVL 11

Author Comment

by:bsharath
ID: 22709356
Yes AT this gets me the users but they reflect on the screen as popup's

Can this be got into an csv with sorting by users...
0
 
LVL 21

Expert Comment

by:AmazingTech
ID: 22711939
Yes. I have been working on that.

I hope you don't use '#' in your AD naming. I'm using it as a separator.

Revision 1:

Column A (User) Column B (Group Membership) Column C...(Nested into Groups)

If User was a member of Group1. Then the CSV file will look like this.
User,Group1

If User was not a member of Group1 but Group2 and Group2 is a member of Group1.
User,Group2,Group1

Column B will always be where User is a member. If User was a member of both Group1 and Group2 and Group2 is a member of Group1.
User1,Group1
User1,Group2,Group1

Change
GroupToSearch = "cn=Domain Admins,cn=Users,dc=domain,dc=com"
Const E_ADS_PROPERTY_NOT_FOUND = &H8000500D
Const ForWriting = 2
CSVFile = "C:\GroupMembership.csv"
GroupToSearch = "cn=Domain Admins,cn=Users,dc=domain,dc=com"
 
Set objDict = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objCSVFile = objFSO.OpenTextFile(CSVFile, ForWriting, True)
 
Set objPrimaryGroup = GetObject("LDAP://" & GroupToSearch)
objPrimaryGroup.GetInfo
 
arrMembers = objPrimaryGroup.GetEx("Member")
 
If Err.Number <> E_ADS_PROPERTY_NOT_FOUND Then
    For Each strmember In arrMembers           
        Call NestedGroup(strmember, Chr(34) & GroupToSearch & Chr(34))
    Next
Else
    wscript.echo vbTab & "No members."
    Err.Clear
End If
 
 
For Each User In objDict.Keys
    arrMultipleGroups = split(objDict(User),"#")
    For Each GroupMembership in arrMultipleGroups
        objCSVFile.WriteLine Chr(34) & User & Chr(34) & "," & GroupMembership
    Next
Next
 
Set objFSO = Nothing
objCSVFile.Close
 
wscript.echo
 
Sub NestedGroup(strGroup, ParentGroup)
    Set objGroup = GetObject _
        ("LDAP://" & strGroup)
    objGroup.GetInfo
 
    If LCase(objGroup.Class) = "group" Then
        PGroup = strGroup  
        arrGroupMembers = objGroup.GetEx("member")
 
        If Err.Number <> E_ADS_PROPERTY_NOT_FOUND Then
            For Each strmember In arrGroupMembers
                Call NestedGroup(strmember, Chr(34) & PGroup & Chr(34) & "," & ParentGroup)
            Next
        End If
    ELSE
        If objDict.Exists(strGroup) Then
            objDict.Item(strGroup) =  ParentGroup & "#" & objDict.Item(strGroup)
        Else
            objDict.Add strGroup, ParentGroup
        End If        
    End If
End Sub

Open in new window

0
 
LVL 21

Expert Comment

by:AmazingTech
ID: 22712207
Oh yeah I use cscript to run my vbs so the wscript.echo is printed in the console rather than a popup box.
0
 
LVL 11

Author Comment

by:bsharath
ID: 22712450
Thanks AT i get the full path of the users or groups . Can i just get the names.
User Name,Goupname
Username,Group1,Group2
0
 
LVL 21

Expert Comment

by:AmazingTech
ID: 22713446
OK. Try this one. I put the on error resume next back in because of groups without members the script will stop.
Const E_ADS_PROPERTY_NOT_FOUND = &H8000500D
Const ForWriting = 2
CSVFile = "C:\GroupMembership.csv"
GroupToSearch = "cn=Domain Admins,cn=Users,dc=domain,dc=com"
 
On Error Resume Next
 
Set objDict = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objCSVFile = objFSO.OpenTextFile(CSVFile, ForWriting, True)
 
Set objPrimaryGroup = GetObject("LDAP://" & GroupToSearch)
objPrimaryGroup.GetInfo
 
arrMembers = objPrimaryGroup.GetEx("Member")
 
If Err.Number <> E_ADS_PROPERTY_NOT_FOUND Then
    For Each strmember In arrMembers
        wscript.echo vbTab & strmember
        Call NestedGroup(strmember, Chr(34) & objPrimaryGroup.cn & Chr(34))
    Next
Else
    wscript.echo vbTab & "No members."
    Err.Clear
End If
 
 
For Each User In objDict.Keys
    arrMultipleGroups = split(objDict(User),"#")
    For Each GroupMembership in arrMultipleGroups
        objCSVFile.WriteLine Chr(34) & User & Chr(34) & "," & GroupMembership
    Next
Next
 
Set objFSO = Nothing
objCSVFile.Close
 
wscript.echo
 
Sub NestedGroup(strGroup, ParentGroup)
    On Error Resume Next
    Set objGroup = GetObject _
        ("LDAP://" & strGroup)
    objGroup.GetInfo
    strGroupCN = objGroup.cn
 
    If LCase(objGroup.Class) = "group" Then
        PGroup = objGroup.cn
        arrGroupMembers = objGroup.GetEx("member")
 
        If Err.Number <> E_ADS_PROPERTY_NOT_FOUND Then
            For Each strmember In arrGroupMembers
                wscript.echo strmember, Chr(34) & PGroup & Chr(34) & "," & ParentGroup
                Call NestedGroup(strmember, Chr(34) & PGroup & Chr(34) & "," & ParentGroup)
            Next
        End If
    ELSE
        If objDict.Exists(strGroupCN) Then
            objDict.Item(strGroupCN) =  ParentGroup & "#" & objDict.Item(strGroupCN)
        Else
            objDict.Add strGroupCN, ParentGroup
        End If        
    End If
End Sub

Open in new window

0
 
LVL 21

Accepted Solution

by:
AmazingTech earned 500 total points
ID: 22713515
objGroup.sAMAccountName

instead of

objGroup.CN
Const E_ADS_PROPERTY_NOT_FOUND = &H8000500D
Const ForWriting = 2
CSVFile = "C:\GroupMembership.csv"
GroupToSearch = "cn=Domain Admins,cn=Users,dc=domain,dc=com"
 
On Error Resume Next
 
Set objDict = CreateObject("Scripting.Dictionary")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objCSVFile = objFSO.OpenTextFile(CSVFile, ForWriting, True)
 
Set objPrimaryGroup = GetObject("LDAP://" & GroupToSearch)
objPrimaryGroup.GetInfo
 
arrMembers = objPrimaryGroup.GetEx("Member")
 
If Err.Number <> E_ADS_PROPERTY_NOT_FOUND Then
    For Each strmember In arrMembers
        wscript.echo vbTab & strmember
        Call NestedGroup(strmember, Chr(34) & objPrimaryGroup.cn & Chr(34))
    Next
Else
    wscript.echo vbTab & "No members."
    Err.Clear
End If
 
 
For Each User In objDict.Keys
    arrMultipleGroups = split(objDict(User),"#")
    For Each GroupMembership in arrMultipleGroups
        objCSVFile.WriteLine Chr(34) & User & Chr(34) & "," & GroupMembership
    Next
Next
 
Set objFSO = Nothing
objCSVFile.Close
 
wscript.echo
 
Sub NestedGroup(strGroup, ParentGroup)
    On Error Resume Next
    Set objGroup = GetObject _
        ("LDAP://" & strGroup)
    objGroup.GetInfo
    strGroupName = objGroup.sAMAccountName
 
    If LCase(objGroup.Class) = "group" Then
        PGroup = objGroup.cn
        arrGroupMembers = objGroup.GetEx("member")
 
        If Err.Number <> E_ADS_PROPERTY_NOT_FOUND Then
            For Each strmember In arrGroupMembers
                wscript.echo strmember, Chr(34) & PGroup & Chr(34) & "," & ParentGroup
                Call NestedGroup(strmember, Chr(34) & PGroup & Chr(34) & "," & ParentGroup)
            Next
        End If
    ELSE
        If objDict.Exists(strGroupName) Then
            objDict.Item(strGroupName) =  ParentGroup & "#" & objDict.Item(strGroupName)
        Else
            objDict.Add strGroupName, ParentGroup
        End If        
    End If
End Sub

Open in new window

0
 
LVL 11

Author Comment

by:bsharath
ID: 22713555
Thank You AT...

Rob & Matthew thank you too...
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
When you see single cell contains number and text, and you have to get any date out of it seems like cracking our heads.
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now