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

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
LVL 11
bsharathAsked:
Who is Participating?
 
AmazingTechCommented:
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
 
tigermattCommented:
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
 
bsharathAuthor Commented:
Thanks but this does not fetch the Root Domain groups....
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
tigermattCommented:
I've no idea in that case. I'm not too good with ADSI scripting - can rejoinder help?
0
 
AmazingTechCommented:
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
 
RobSampsonCommented:
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
 
RobSampsonCommented:
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
 
bsharathAuthor Commented:
Hi
Yes Rob that would be better....
0
 
RobSampsonCommented:
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
 
bsharathAuthor Commented:
Ok Rob i shall get the results tommorow...
0
 
bsharathAuthor Commented:
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
 
bsharathAuthor Commented:
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
 
RobSampsonCommented:
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
 
bsharathAuthor Commented:
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
 
bsharathAuthor Commented:
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
 
bsharathAuthor Commented:
Hi Matthew \ Rob \ AT

Just wanted to let you know my joy.

I have been blessed with a Boy baby today... :-)
0
 
AmazingTechCommented:
Congratulations! Is this your first child?
0
 
bsharathAuthor Commented:
Thank U AT Yes my first... :-)
0
 
AmazingTechCommented:
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
 
RobSampsonCommented:
Sharath, congratulations!!!  I'm sure you will have a very enjoyable experience with your new child!

Rob.
0
 
bsharathAuthor Commented:
Thanks Rob....
0
 
tigermattCommented:
Sharath,

Congratulations all around from me too!!

Matthew
0
 
bsharathAuthor Commented:
Thanks Matthew...
0
 
bsharathAuthor Commented:
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
 
bsharathAuthor Commented:
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
 
AmazingTechCommented:
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
 
AmazingTechCommented:
Oh yeah I use cscript to run my vbs so the wscript.echo is printed in the console rather than a popup box.
0
 
bsharathAuthor Commented:
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
 
AmazingTechCommented:
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
 
bsharathAuthor Commented:
Thank You AT...

Rob & Matthew thank you too...
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.