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
339 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
 
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

760 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

22 Experts available now in Live!

Get 1:1 Help Now