• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 457
  • Last Modified:

Query each user and get the users group details as this.

Hi,

Query each user and get the users group details as this.
I want help with a script that can query an Ou thats mentioned and get the membership of that user in the below format. Fo all users in the Ou.
I have the groups in the Root Domain and Child. So all the Membership has to be fetched.

Suugam@plc.com;i.S;FulUsers;R1;Drs

Regards
sharath
0
bsharath
Asked:
bsharath
  • 21
  • 21
  • 3
  • +1
1 Solution
 
exx1976Commented:
"An OU that's mentioned.."

Scotty:  "Computer, make transparent aluminum!"


Where will this OU be "mentioned"?  In a text file?  Should the script prompt for input?
0
 
bsharathAuthor Commented:
;-)
i want it hardcoded within the script
0
 
exx1976Commented:
HTH,
exx
Set oFS = CreateObject("scripting.filesystemobject")
Set oFile = oFS.CreateTextFile("c:\myfile.txt")
Set oOU = GetObject("LDAP://OU=myou,DC=domain,DC=local")
For each oUser in oOU
       if oUser.Class = "user" then
             data = oUser.SamAccountName & ";"
             for each group in oUser.groups
                    data = data & group.name & ";"
             Next
       End If
       data = left(data,Len(data)-1)
       oFile.writeline(data)
next

                   

Open in new window

0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
bsharathAuthor Commented:
I want to pick the email addresses and query and get the email ids also in theresults file
and
i dont gets group membership from other Domains. As mentioned i have root Domain where all my groups are available
0
 
exx1976Commented:
What?

What do you mean pick the email addresses?  You said you wanted it based on OU.

Other domains have nothing to do with anything, this is getting information from the user, not from the group.  It doesn't matter where the group is located.  If it's on the user object, it should show up.
0
 
bsharathAuthor Commented:
Sorry i think i was not clear
I have domains as this

RootDomain
 >> ChildDomain1
 >> ChildDomain2
 >> ChildDomain3

i have the users in ChildDomain1 and groups in Root Domain
What happens is if the user is member of groups in the same childDomain your script retrieves group names. If the Group is in other Domains it does not.
So need to get the data quering other groups in other domains also.

For the email part. I need to get the data like this in the results file
Emailaddress@plc.com;Shildgroupname;Rootgroupname
0
 
RobSampsonCommented:
If you run this:
dsquery user -samid "username" | dsget user -memberof

do you get the list for a particular user?

Rob.
0
 
bsharathAuthor Commented:
Rob i get but of the local Domain only
0
 
bsharathAuthor Commented:
Rob i need to get all groups where is user is a member from Root Domain as well in the same format
0
 
jostranderCommented:
Hello again Sharath.  I think you'll need to distinguish the different domains somehow in the output.  


Example 1 (email address & dns domain name):
abcuseremail@abc.com;abc.com\Domain Users;abc.com\Some Group1;child.abc.com\Domain Users

Example 2 (email address & netbios domain name):
abcuseremail@abc.com;ABC\Domain Users;ABC\Some Group1;ABCCHILD\Domain Users

Example 3 (user principal name):
abcuser@abc.com;Domain Users;Some Group1
abcuser@child.abc.com;Domain Users

Example 4 (distinguished names):
abcuseremail@abc.com;CN=Domain Users,DC=abc,DC=com;CN=Some Group1;OU=test,DC=abc,DC=com;CN=Domain Users,DC=child,DC=abc,DC=com

Example 5 (no distinction):
abcuseremail@abc.com;Domain Users;Some Group1;Domain Users
(could eliminate dupes if needed)

How would you like to distinguish the different domains in the output?
In the OU that is specified, are there any accounts that may have a duplicate email address of another account?
Do the email addresses match the user principal name of the account in the specified OU?

Here is a sample based off the other script I did for you earlier today.  It's currently using the samaccountname/userprincipalname...
'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"

'Name of your logfile
strLogFileName="D:\GroupMembership.txt"

'List of DNS Domains,separated by comma
strDNSdomainList="somewhere.com,child.somewhere.com"

'------------------------------------------------


Set WshShell=CreateObject("Wscript.Shell")
Set oDict=CreateObject("Scripting.Dictionary")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If

Set fso = CreateObject("scripting.filesystemobject") 
Set oFile = fso.OpenTextFile(strLogFileName,2,true)

arrDomains=split(strDNSdomainList,",")

'Make dictionary of users in OU
Set objOU = GetObject("LDAP://" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 
		For each domain in arrDomains
			oDict.Add objUser.sAMAccountName & "@" & domain ,""
		Next
	End If
Next

For each domain in arrDomains
	ListGroups domain
Next

For each key in oDict.Keys
	oFile.WriteLine key & ";" & oDict(key)
Next

oFile.close

wscript.echo
wscript.echo "Operation Complete."
wscript.echo "See logfile:  " & strLogFileName

Sub ListGroups(myDNSdomain)

	Set objRootDSE = GetObject("LDAP://" & myDNSdomain & "/rootDSE")
	strRootDSE = objRootDSE.Get("defaultNamingContext")
	
	strADsPath=""
	strADsPath="LDAP://" & myDNSDomain & "/" & strRootDSE

	Const ADS_SCOPE_SUBTREE = 2

	Set objConnection = CreateObject("ADODB.Connection")
	Set objCommand =   CreateObject("ADODB.Command")
	objConnection.Provider = "ADsDSOObject"
	objConnection.Open "Active Directory Provider"
	Set objCommand.ActiveConnection = objConnection
	
	objCommand.Properties("Page Size") = 1000
	objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
	
	objCommand.CommandText = _
		"SELECT ADsPath,CN FROM '" & strADsPath & "' WHERE objectCategory='group' "
	
	Set objRecordSet = objCommand.Execute
	
	If NOT objRecordSet.EOF then objRecordSet.MoveFirst

	While NOT objRecordSet.EOF
		strADsPath_group=""
		strADsPath_group= objRecordSet.Fields("ADsPath").value
		strGroupCN=""
		strGroupCN= objRecordSet.Fields("CN").value
		Set objGroup=GetObject(strADsPath_group)
		For each objUser in objGroup.Members
			myUser=""
			myUser=objUser.sAMAccountName & "@" & myDNSdomain
			If oDict.Exists(myUser) then
				oDict(myUser)=oDict(myUser) & _
					objGroup.CN &  ";"
				wscript.echo myUser & vbTab & objGroup.CN
			End If
		Next
		
		Set objGroup=Nothing
		objRecordSet.MoveNext
	Wend
	
	Set objConnection=Nothing
	Set objCommand=Nothing
	Set objRecordSet=Nothing
End Sub

Open in new window

0
 
jostranderCommented:
Here's some sample output querying for samaccount name & displaying user principal name:

abcuser@somewhere.com;Group Policy Creator Owners;Domain Admins;Schema Admins;Enterprise Admins;Administrators;Helpdesk;Tech Support;Group Number3;
abcuser@child.somewhere.com;Domain Admins;Enterprise Admins;Schema Admins;
testuser1@somewhere.com;Group Number1;Group Number3;
testuser1@child.somewhere.com;
testuser2@somewhere.com;Group Number1;Group Number2;Group Number3;
testuser2@child.somewhere.com;
testuser3@somewhere.com;Group Number2;
testuser3@child.somewhere.com;
0
 
bsharathAuthor Commented:
Hi jostrander,

The code runs fine
I need these
Example 5 (no distinction):
abcuseremail@abc.com;Domain Users;Some Group1;Domain Users
(could eliminate dupes if needed)

I want the data for both Domains to look as this
Sharath@plc.com;Group1;group2
No matter which domain they are from but it all needs to be in 1 line
Just the group names
0
 
jostranderCommented:
Please try this one:
'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"

'Name of your logfile
strLogFileName="D:\GroupMembership.txt"

'List of DNS Domains,separated by comma
strDNSdomainList="somewhere.com,child.somewhere.com"

'------------------------------------------------


Set WshShell=CreateObject("Wscript.Shell")
Set oDict=CreateObject("Scripting.Dictionary")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If

Set fso = CreateObject("scripting.filesystemobject") 
Set oFile = fso.OpenTextFile(strLogFileName,2,true)

arrDomains=split(strDNSdomainList,",")

'Make dictionary of users in OU
Set objOU = GetObject("LDAP://" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 
		oDict.Add objUser.sAMAccountName,objUser.mail & ";"
	End If
Next

For each domain in arrDomains
	ListGroups domain
Next

For each key in oDict.Keys
	oFile.WriteLine oDict(key)
Next

oFile.close

wscript.echo
wscript.echo "Operation Complete."
wscript.echo "See logfile:  " & strLogFileName

Sub ListGroups(myDNSdomain)

	Set objRootDSE = GetObject("LDAP://" & myDNSdomain & "/rootDSE")
	strRootDSE = objRootDSE.Get("defaultNamingContext")
	
	strADsPath=""
	strADsPath="LDAP://" & myDNSDomain & "/" & strRootDSE

	Const ADS_SCOPE_SUBTREE = 2

	Set objConnection = CreateObject("ADODB.Connection")
	Set objCommand =   CreateObject("ADODB.Command")
	objConnection.Provider = "ADsDSOObject"
	objConnection.Open "Active Directory Provider"
	Set objCommand.ActiveConnection = objConnection
	
	objCommand.Properties("Page Size") = 1000
	objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
	
	objCommand.CommandText = _
		"SELECT ADsPath,CN FROM '" & strADsPath & "' WHERE objectCategory='group' "
	
	Set objRecordSet = objCommand.Execute
	
	If NOT objRecordSet.EOF then objRecordSet.MoveFirst

	While NOT objRecordSet.EOF
		strADsPath_group=""
		strADsPath_group= objRecordSet.Fields("ADsPath").value
		strGroupCN=""
		strGroupCN= objRecordSet.Fields("CN").value
		Set objGroup=GetObject(strADsPath_group)
		For each objUser in objGroup.Members
			myUser=""
			myUser=objUser.sAMAccountName
			If oDict.Exists(myUser) then
				arrGroups=split(oDict(myUser),";")
				add=True
				For each grp in arrGroups
					If grp=objGroup.CN then add=False
				Next
				If add=True then
					oDict(myUser)=oDict(myUser) & objGroup.CN &  ";"
					wscript.echo myDNSdomain & "..." & myUser & vbTab & objGroup.CN
				End If
				arrGroups=""
			End If
		Next
		
		Set objGroup=Nothing
		objRecordSet.MoveNext
	Wend
	
	Set objConnection=Nothing
	Set objCommand=Nothing
	Set objRecordSet=Nothing
End Sub

Open in new window

0
 
RobSampsonCommented:
Hi Joe, can I ask....how does your code retrieve groups that in the root domain?  Is it because you bind to the root domain first, then find the user from the child domain?

I don't have any sub domains, so I have never been able to test any of the code I have given Sharath....

Thanks,

Rob.
0
 
jostranderCommented:
Hey Rob,  I treat the child & root domains as if they were completely separate domains.  Then just query each one like ldap://domain1.com/<adsipath> and ldap://xxx.domain1.com/<adsipath>.  Assuming DNS has info for the domains, it works just like specifying a server:  ldap://server1/<adsipath>.

0
 
RobSampsonCommented:
But if the user exists in Child domain, and not Root domain, how does your code see that User in Child Domain is a member of a Root domain group?  As you can see above, DSQuery and DSGet only returned groups from the local domain.

Rob.
0
 
jostranderCommented:
I'm doing it the slow way.  I actually have it chech every group in root and child, looking for samaccountname in each group.
0
 
bsharathAuthor Commented:
Thanks
Its very slow. Any way to speed this up
0
 
bsharathAuthor Commented:
any views on this
0
 
jostranderCommented:
Sharath,
I'm sure there's a way to speed it up, just don't know at the moment.  I'll think about this...

Rob,
I forgot to mention... I worked on another script for Sharath that had 2 domains, each one containing an account of the same name.  I assumed this was for the same domains, so the method I'm using here is attempting to find account in both domains.  This won't list any foreign security principals, only accounts that match samaccountnames.  Hopefully my assumption is correct :)
0
 
jostranderCommented:
Sharath,

This version is infinitely faster... and should find all groups even if the only user account is in the local domain.
'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"

'Name of your logfile
strLogFileName="D:\GroupMembership.txt"

'DNS Domain info
strLocalDomain="somewhere.com"
strRemoteDomain="remote.somewhere.com"

'------------------------------------------------

Set WshShell=CreateObject("Wscript.Shell")
Set fso=CreateObject("Scripting.FileSystemObject")
Set oDict=CreateObject("Scripting.Dictionary")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If


Set oLogFile=fso.OpenTextFile(strLogFileName,2,true)

'Find users in OU
Set objOU = GetObject("LDAP://" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 

		'Get the user SID
		arrSid = objUser.objectSid 
		strSidHex = OctetToHexStr(arrSid) 
		strSidDec = HexStrToDecStr(strSidHex) 

		
		'Get local domain groups
		localGroups=GetGroups(objUser.DistinguishedName,strLocalDomain)
		
		'Get remote domain groups
		remoteGroups=GetGroups(strSidDec,strRemoteDomain)
		
		allGroups=localGroups & remoteGroups
		If right(allGroups,1)=";" then allGroups=left(allGroups,len(allGroups)-1)
		
		'Output objUser.sAMAccountName & "@" & strLocalDomain & ";" & localGroups & remoteGroups
		Output objUser.mail & ";" & allGroups

		arrSid=""
		strSidHex=""
		strSidDec=""
		localGroups=""
		remoteGroups=""
		allGroups=""
		
		
	End If
Next


wscript.echo ""
wscript.echo "Operation complete.  See Log:  " & strLogFileName



'Close logfile
oLogFile.close


Sub Output(txt)
	wscript.echo txt
	oLogFile.writeLine txt
End Sub


Function GetGroups(strUserDN,strDNSdomain)
	Const ADS_SCOPE_SUBTREE = 2
	
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	Set adoCommand.ActiveConnection = adoConnection
	
	Set objRootDSE = GetObject("LDAP://" & strDNSdomain & "/RootDSE")
	strRootDSE = objRootDSE.Get("defaultNamingContext")
	
	strBase = "<LDAP://" & strDNSdomain & "/" & strRootDSE & ">"
	
	If Instr(strUserDN,"S-1-5-21") then
		strMember="CN=" & strUserDN & ",CN=ForeignSecurityPrincipals," & strRootDSE
	Else
		strMember=strUserDN
	End If

	strFilter = "(&(objectCategory=group)(member=" & strMember & "))"
	
	strAttributes = "CN,ADsPath"
	
	strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
	adoCommand.CommandText = strQuery
	adoCommand.Properties("Page Size") = 1000
	adoCommand.Properties("Timeout") = 30
	adoCommand.Properties("Cache Results") = False
	
	Set adoRecordset = adoCommand.Execute
	
	Do Until adoRecordset.EOF
		strCN = adoRecordset.Fields("CN").Value
		strADsPath = adoRecordset.Fields("ADsPath").value
	
		AllGroups=AllGroups & strCN & ";"
	
		adoRecordset.MoveNext
		strCN=""
		strADsPath=""
	Loop
	
	adoRecordset.Close
	adoConnection.Close

	GetGroups=AllGroups

End Function




Function OctetToHexStr(arrbytOctet) 
	' Function to convert OctetString (byte array) to Hex string. 
	
	Dim k 
	OctetToHexStr = "" 
	For k = 1 To Lenb(arrbytOctet) 
	OctetToHexStr = OctetToHexStr _ 
	& Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2) 
	Next 
End Function 
	
Function HexStrToDecStr(strSid) 
	on error resume next
	' Function to convert hex Sid to decimal (SDDL) Sid. 
	Dim arrbytSid, lngTemp, j 
	
	ReDim arrbytSid(Len(strSid)/2 - 1) 
	For j = 0 To UBound(arrbytSid) 
	arrbytSid(j) = CInt("&H" & Mid(strSid, 2*j + 1, 2)) 
	Next 
	
	HexStrToDecStr = "S-" & arrbytSid(0) & "-" _ 
	& arrbytSid(1) & "-" & arrbytSid(8) 
	
	lngTemp = arrbytSid(15) 
	if err.number <> 0 then 
		msgbox err.number & vbcrlf & err.description & vbCrLf & strSid
		wscript.quit
	end if
	lngTemp = lngTemp * 256 + arrbytSid(14) 
	lngTemp = lngTemp * 256 + arrbytSid(13) 
	lngTemp = lngTemp * 256 + arrbytSid(12) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(19) 
	lngTemp = lngTemp * 256 + arrbytSid(18) 
	lngTemp = lngTemp * 256 + arrbytSid(17) 
	lngTemp = lngTemp * 256 + arrbytSid(16) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(23) 
	lngTemp = lngTemp * 256 + arrbytSid(22) 
	lngTemp = lngTemp * 256 + arrbytSid(21) 
	lngTemp = lngTemp * 256 + arrbytSid(20) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(25) 
	lngTemp = lngTemp * 256 + arrbytSid(24) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 

End Function

Open in new window

0
 
bsharathAuthor Commented:
Thanks
Its perfect but one Ou did not get any groups. I will test that and get back
i need to add one more Domain into it
When i mention as this it does not fetch from the 3rd mention domain

'DNS Domain info
strLocalDomain="group.co.uk"
strRemoteDomain="de.group.co.uk"
strRemoteDomain="Eoi.group.co.uk"
0
 
jostranderCommented:
This will allow for multiple remote domains:
'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"

'Name of your logfile
strLogFileName="D:\GroupMembership.txt"


'Local DNS domain
strLocalDomain="group.co.uk"

'Remote DNS domains, separated by comma
strRemoteDomainList="de.group.co.uk,eoi.group.co.uk"

'------------------------------------------------

Set WshShell=CreateObject("Wscript.Shell")
Set fso=CreateObject("Scripting.FileSystemObject")
Set oDict=CreateObject("Scripting.Dictionary")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If


Set oLogFile=fso.OpenTextFile(strLogFileName,2,true)

'Find users in OU
Set objOU = GetObject("LDAP://" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 

		'Get the user SID
		arrSid = objUser.objectSid 
		strSidHex = OctetToHexStr(arrSid) 
		strSidDec = HexStrToDecStr(strSidHex) 

		
		'Get local domain groups
		localGroups=GetGroups(objUser.DistinguishedName,strLocalDomain)
		
		'Get remote domain groups
		arrRemoteDomains=split(strRemoteDomainList,",")
		For each strRemoteDomain in arrRemoteDomains
			remoteGroups=remoteGroups & GetGroups(strSidDec,strRemoteDomain)
		Next
		
		allGroups=localGroups & remoteGroups
		If right(allGroups,1)=";" then allGroups=left(allGroups,len(allGroups)-1)
		
		'Output objUser.sAMAccountName & "@" & strLocalDomain & ";" & localGroups & remoteGroups
		Output objUser.mail & ";" & allGroups

		arrSid=""
		strSidHex=""
		strSidDec=""
		localGroups=""
		remoteGroups=""
		allGroups=""
		
		
	End If
Next


wscript.echo ""
wscript.echo "Operation complete.  See Log:  " & strLogFileName



'Close logfile
oLogFile.close


Sub Output(txt)
	wscript.echo txt
	oLogFile.writeLine txt
End Sub


Function GetGroups(strUserDN,strDNSdomain)
	Const ADS_SCOPE_SUBTREE = 2
	
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	Set adoCommand.ActiveConnection = adoConnection
	
	Set objRootDSE = GetObject("LDAP://" & strDNSdomain & "/RootDSE")
	strRootDSE = objRootDSE.Get("defaultNamingContext")
	
	strBase = "<LDAP://" & strDNSdomain & "/" & strRootDSE & ">"
	
	If Instr(strUserDN,"S-1-5-21") then
		strMember="CN=" & strUserDN & ",CN=ForeignSecurityPrincipals," & strRootDSE
	Else
		strMember=strUserDN
	End If

	strFilter = "(&(objectCategory=group)(member=" & strMember & "))"
	
	strAttributes = "CN,ADsPath"
	
	strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
	adoCommand.CommandText = strQuery
	adoCommand.Properties("Page Size") = 1000
	adoCommand.Properties("Timeout") = 30
	adoCommand.Properties("Cache Results") = False
	
	Set adoRecordset = adoCommand.Execute
	
	Do Until adoRecordset.EOF
		strCN = adoRecordset.Fields("CN").Value
		strADsPath = adoRecordset.Fields("ADsPath").value
	
		AllGroups=AllGroups & strCN & ";"
	
		adoRecordset.MoveNext
		strCN=""
		strADsPath=""
	Loop
	
	adoRecordset.Close
	adoConnection.Close

	GetGroups=AllGroups

End Function




Function OctetToHexStr(arrbytOctet) 
	' Function to convert OctetString (byte array) to Hex string. 
	
	Dim k 
	OctetToHexStr = "" 
	For k = 1 To Lenb(arrbytOctet) 
	OctetToHexStr = OctetToHexStr _ 
	& Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2) 
	Next 
End Function 
	
Function HexStrToDecStr(strSid) 
	on error resume next
	' Function to convert hex Sid to decimal (SDDL) Sid. 
	Dim arrbytSid, lngTemp, j 
	
	ReDim arrbytSid(Len(strSid)/2 - 1) 
	For j = 0 To UBound(arrbytSid) 
	arrbytSid(j) = CInt("&H" & Mid(strSid, 2*j + 1, 2)) 
	Next 
	
	HexStrToDecStr = "S-" & arrbytSid(0) & "-" _ 
	& arrbytSid(1) & "-" & arrbytSid(8) 
	
	lngTemp = arrbytSid(15) 
	if err.number <> 0 then 
		msgbox err.number & vbcrlf & err.description & vbCrLf & strSid
		wscript.quit
	end if
	lngTemp = lngTemp * 256 + arrbytSid(14) 
	lngTemp = lngTemp * 256 + arrbytSid(13) 
	lngTemp = lngTemp * 256 + arrbytSid(12) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(19) 
	lngTemp = lngTemp * 256 + arrbytSid(18) 
	lngTemp = lngTemp * 256 + arrbytSid(17) 
	lngTemp = lngTemp * 256 + arrbytSid(16) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(23) 
	lngTemp = lngTemp * 256 + arrbytSid(22) 
	lngTemp = lngTemp * 256 + arrbytSid(21) 
	lngTemp = lngTemp * 256 + arrbytSid(20) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(25) 
	lngTemp = lngTemp * 256 + arrbytSid(24) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 

End Function

Open in new window

0
 
bsharathAuthor Commented:
A little confused

'Local DNS domain
strLocalDomain="group.co.uk"

'Remote DNS domains, separated by comma
strRemoteDomainList="Eio.group.co.uk,de.group.co.uk"

Group.co.uk is my root Domain and other 2 child domain.
I get all the groups from the root but none from the child domain
I tried placing the child domain in the local domain and none are listed
0
 
jostranderCommented:
the Local would be local to the OU you are checking ("OU=Countries,DC=Group,DC=co,DC=uk")

Which domain has the OU and accounts?

0
 
bsharathAuthor Commented:
Users are in Local Domain where the path is mentioned OU=
And the groups are in different Domains
0
 
jostranderCommented:
Could you do a quick test for me?

Modify this code to reflect the ADsPath of a valid group in the domain de.group.co.uk, and send an example of what the output looks like.

(run with cscript)
strADsPath="LDAP://de.group.co.uk/CN=My Group1,OU=Some OU,DC=de,dc=group,dc=co,dc=uk"
Set objGroup=GetObject(strADsPath)
For each objUser in objGroup.Members
	wscript.echo objUser.ADsPath
Next

Open in new window

0
 
jostranderCommented:
Choose a group that has at least 1 member from the root domain group.co.uk.  I'm looking to see if the name comes through in SID format (s-1-5-21...)
0
 
bsharathAuthor Commented:
I get this

---------------------------
Windows Script Host
---------------------------
LDAP://group.co.uk/CN=La rs,OU=Naers,C=Eio,DC=Group,DC=co,DC=uk
---------------------------
OK  
---------------------------
0
 
jostranderCommented:
Oh, I see now.  I wrote the earlier version to work with domains that are in separate forests but have a trust relationship.  It works pretty good for that scenario.  

I should be able to modify it to work for root/child domains in the same forest now that I see your output.
0
 
jostranderCommented:
K, I think it was a little easier than I was making it... I was doing testing in 2 separate forests (also useful).  I setup a complete new environment with root & child domain and tested this script with it.

Please try and let me know how it works for you:
'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"


'Name of your logfile
strLogFileName="D:\GroupMembership.txt"


'Local DNS domain
strLocalDomain="group.co.uk"


'Remote DNS domains, separated by comma
strRemoteDomainList="de.group.co.uk,eoi.group.co.uk"


'------------------------------------------------

Set WshShell=CreateObject("Wscript.Shell")
Set fso=CreateObject("Scripting.FileSystemObject")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If


Set oLogFile=fso.OpenTextFile(strLogFileName,2,true)

'Find users in OU
Set objOU = GetObject("LDAP://" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 

		
		'Get local domain groups
		localGroups=GetGroups(objUser.DistinguishedName,strLocalDomain)
		
		'Get remote domain groups
		arrRemoteDomains=split(strRemoteDomainList,",")
		For each strRemoteDomain in arrRemoteDomains
			remoteGroups=remoteGroups & GetGroups(objUser.DistinguishedName,strRemoteDomain)
		Next
		
		allGroups=localGroups & remoteGroups
		If right(allGroups,1)=";" then allGroups=left(allGroups,len(allGroups)-1)
		
		'Output objUser.sAMAccountName & "@" & strLocalDomain & ";" & localGroups & remoteGroups
		Output objUser.mail & ";" & allGroups

		localGroups=""
		remoteGroups=""
		allGroups=""
		
		
	End If
Next


wscript.echo ""
wscript.echo "Operation complete.  See Log:  " & strLogFileName



'Close logfile
oLogFile.close


Sub Output(txt)
	wscript.echo txt
	oLogFile.writeLine txt
End Sub


Function GetGroups(strUserDN,strDNSdomain)
	Const ADS_SCOPE_SUBTREE = 2
	
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	Set adoCommand.ActiveConnection = adoConnection
	
	Set objRootDSE = GetObject("LDAP://" & strDNSdomain & "/RootDSE")
	strRootDSE = objRootDSE.Get("defaultNamingContext")
	'strRootDSE="DC=" & replace(strDNSdomain,".",",DC=")
	
	strBase = "<LDAP://" & strDNSdomain & "/" & strRootDSE & ">"
	
	strFilter = "(&(objectCategory=group)(member=" & strUserDN & "))"
	
	strAttributes = "CN,ADsPath"
	
	strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
	adoCommand.CommandText = strQuery
	adoCommand.Properties("Page Size") = 1000
	adoCommand.Properties("Timeout") = 30
	adoCommand.Properties("Cache Results") = False
	
	Set adoRecordset = adoCommand.Execute
	
	Do Until adoRecordset.EOF
		strCN = adoRecordset.Fields("CN").Value
		strADsPath = adoRecordset.Fields("ADsPath").value
	
		AllGroups=AllGroups & strCN & ";"
	
		adoRecordset.MoveNext
		strCN=""
		strADsPath=""
	Loop
	
	adoRecordset.Close
	adoConnection.Close

	GetGroups=AllGroups

End Function

Open in new window

0
 
bsharathAuthor Commented:
Thanks
Now it works for the child Domain. Both of them but not the root domain
strLocalDomain= I have the domain path where i have the users OU path and this is local
strRemoteDomainList= I have 2 of the remote domains one is child and another is root Domain
0
 
jostranderCommented:
I've ran a few tests and I'm having trouble replicating the issue.  Just to be sure I have the information correct...  the accounts and the specified OU are in a child domain and you're querying for group membership in a child domain and a root domain, correct?

something like this?
strLocalDomain="eoi.group.co.uk"
strRemoteDomainList="de.group.co.uk,group.co.uk"

All domains are in the same forest, correct?
0
 
bsharathAuthor Commented:
Yes all Domains in same forest
strLocalDomain="eoi.group.co.uk" ( Root Domain)
strRemoteDomainList="de.group.co.uk,group.co.uk" (Child Domains)
0
 
jostranderCommented:
I'll have to think about this and get back to you tomorrow.  If it finds the groups in the 2 domains you have specified as remote, that means that its finding the user adspath from the domain specified as local... But can't read the group membership.  Does the account you are logged in with have permission to read group membership in that domain?
0
 
bsharathAuthor Commented:
yes it does have permissions
The previous script was working for that specific Root Domain. Now it does not work for that and works for the child Domain
0
 
jostranderCommented:
Since the previous script was working for one domain but not the other... and now vice-versa, I think one domain was showing the group member as a Foreign Security principal.  I've modified the script so that it should work for multiple scenarios.

So far, I've tested these scenarios successfully:
2 domains in 2 forests (with trust relationship between domains)
2 domains in same forest (root/child scenario)
3 domains in 2 forests (1 root + 1 child and separate forest trusted domain)


'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"


'Local DNS domain
strLocalDomain="group.co.uk"


'Remote DNS domains, separated by comma
strRemoteDomainList="de.group.co.uk,eoi.group.co.uk"


'Name of your logfile
strLogFileName="D:\GroupMembership.txt"

'------------------------------------------------

Set WshShell=CreateObject("Wscript.Shell")
Set oDict=CreateObject("Scripting.Dictionary")
Set fso=CreateObject("Scripting.FileSystemObject")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If


Set oLogFile=fso.OpenTextFile(strLogFileName,2,true)

'Find users in OU
Set objOU = GetObject("LDAP://" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 

		strDN=objUser.DistinguishedName
		strMail=objUser.mail
		
		If strMail<>"" then 
			oDict.Add strDN,objUser.mail & ";"
		Else
			oDict.Add strDN,objUser.sAMAccountName & "@" & strLocalDomain & ";"
		End If
		

		'Get the user SID
		arrSid = objUser.objectSid 
		strSidHex = OctetToHexStr(arrSid) 
		strSidDec = HexStrToDecStr(strSidHex) 
		
		
		'Get local domain groups
		GetGroups strDN,strSidDec,strLocalDomain
		
		'Get remote domain groups
		arrRemoteDomains=split(strRemoteDomainList,",")
		For each strRemoteDomain in arrRemoteDomains
			GetGroups strDN,strSidDec,strRemoteDomain
		Next
		
		AllGroups=oDict(strDN)
		If right(AllGroups,1)=";" then oDict(strDN)=left(AllGroups,len(AllGroups)-1)
		
		Output oDict(strDN)

		strSidDec=""
		strSidHex=""
		arrSid=""
		strDN=""
		strMail=""
		AllGroups=""
		
	End If
Next


wscript.echo ""
wscript.echo "Operation complete.  See Log:  " & strLogFileName



'Close logfile
oLogFile.close


Sub Output(txt)
	wscript.echo txt
	oLogFile.writeLine txt
End Sub


Sub GetGroups(strUserDN,strUserSID,strDNSdomain)
	
	
	Const ADS_SCOPE_SUBTREE = 2
	
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	Set adoCommand.ActiveConnection = adoConnection
	
	Set objRootDSE = GetObject("LDAP://" & strDNSdomain & "/RootDSE")
	strRootDSE = objRootDSE.Get("defaultNamingContext")

	
	strForeignSID="CN=" & strUserSID & ",CN=ForeignSecurityPrincipals," & strRootDSE
	
	strBase = "<LDAP://" & strDNSdomain & "/" & strRootDSE & ">"
	
	strFilter = "(&(objectCategory=group)(|(member=" & strUserDN & ")(member=" & strForeignSID & ")))"
	
	strAttributes = "CN,ADsPath"
	
	strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
	adoCommand.CommandText = strQuery
	adoCommand.Properties("Page Size") = 1000
	adoCommand.Properties("Timeout") = 30
	adoCommand.Properties("Cache Results") = False
	
	Set adoRecordset = adoCommand.Execute
	
	Do Until adoRecordset.EOF
		strCN = adoRecordset.Fields("CN").Value
		strADsPath = adoRecordset.Fields("ADsPath").value
	
		'Eliminate duplicates
		AddMe=True
		arrGroups=split(oDict(strUserDN),";")
		For each grp in arrGroups
			If grp=strCN then AddMe=False
		Next
		
		If AddMe=True then oDict(strUserDN)=oDict(strUserDN) & strCN & ";"
			
		adoRecordset.MoveNext
		strCN=""
		strADsPath=""
	Loop
	
	adoRecordset.Close
	adoConnection.Close

End Sub



Function OctetToHexStr(arrbytOctet) 
	' Function to convert OctetString (byte array) to Hex string. 
	
	Dim k 
	OctetToHexStr = "" 
	For k = 1 To Lenb(arrbytOctet) 
	OctetToHexStr = OctetToHexStr _ 
	& Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2) 
	Next 
End Function 
	
Function HexStrToDecStr(strSid) 
	on error resume next
	' Function to convert hex Sid to decimal (SDDL) Sid. 
	Dim arrbytSid, lngTemp, j 
	
	ReDim arrbytSid(Len(strSid)/2 - 1) 
	For j = 0 To UBound(arrbytSid) 
	arrbytSid(j) = CInt("&H" & Mid(strSid, 2*j + 1, 2)) 
	Next 
	
	HexStrToDecStr = "S-" & arrbytSid(0) & "-" _ 
	& arrbytSid(1) & "-" & arrbytSid(8) 
	
	lngTemp = arrbytSid(15) 
	if err.number <> 0 then 
		msgbox err.number & vbcrlf & err.description & vbCrLf & strSid
		wscript.quit
	end if
	lngTemp = lngTemp * 256 + arrbytSid(14) 
	lngTemp = lngTemp * 256 + arrbytSid(13) 
	lngTemp = lngTemp * 256 + arrbytSid(12) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(19) 
	lngTemp = lngTemp * 256 + arrbytSid(18) 
	lngTemp = lngTemp * 256 + arrbytSid(17) 
	lngTemp = lngTemp * 256 + arrbytSid(16) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(23) 
	lngTemp = lngTemp * 256 + arrbytSid(22) 
	lngTemp = lngTemp * 256 + arrbytSid(21) 
	lngTemp = lngTemp * 256 + arrbytSid(20) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(25) 
	lngTemp = lngTemp * 256 + arrbytSid(24) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 

End Function

Open in new window

0
 
bsharathAuthor Commented:
Still does not get groups from root domain

'Local DNS domain
strLocalDomain="group.co.uk"  (ROOT DOMAIN)


'Remote DNS domains, separated by comma
strRemoteDomainList="Eur.group.co.uk,Dev.group.co.uk" (2 CHILD DOMAINS)
0
 
jostranderCommented:
I'm guessing that the account you are logged in with is not located in the root domain?

I think we could probably just change the line:
Set objOU = GetObject("LDAP://" & strOU)
to:
Set objOU = GetObject("LDAP://" & strLocalDomain & "/" & strOU)

If that doesn't work, try this:
'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"

'Local DNS domain
strLocalDomain="group.co.uk"

'Remote DNS domains, separated by comma
strRemoteDomainList="de.group.co.uk,eoi.group.co.uk"

'Name of your logfile
strLogFileName="D:\GroupMembership.txt"

'------------------------------------------------

Set WshShell=CreateObject("Wscript.Shell")
Set oDict=CreateObject("Scripting.Dictionary")
Set fso=CreateObject("Scripting.FileSystemObject")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If


Set oLogFile=fso.OpenTextFile(strLogFileName,2,true)

'Find users in OU
Set objOU = GetObject("LDAP://" & strLocalDomain & "/" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 

		strDN=objUser.DistinguishedName
		strMail=objUser.mail
		
		If strMail<>"" then 
			oDict.Add strDN,objUser.mail & ";"
		Else
			oDict.Add strDN,objUser.sAMAccountName & "@" & strLocalDomain & ";"
		End If
		

		'Get the user SID
		arrSid = objUser.objectSid 
		strSidHex = OctetToHexStr(arrSid) 
		strSidDec = HexStrToDecStr(strSidHex) 
		
		
		'Get local domain groups
		'GetGroups strDN,strSidDec,strLocalDomain
		GetGroups2 strDN,strLocalDomain
		
		'Get remote domain groups
		arrRemoteDomains=split(strRemoteDomainList,",")
		For each strRemoteDomain in arrRemoteDomains
			GetGroups strDN,strSidDec,strRemoteDomain
		Next
		
		AllGroups=oDict(strDN)
		If right(AllGroups,1)=";" then oDict(strDN)=left(AllGroups,len(AllGroups)-1)
		
		Output oDict(strDN)

		strSidDec=""
		strSidHex=""
		arrSid=""
		strDN=""
		strMail=""
		AllGroups=""
		arrGroups=""
		
	End If
Next


wscript.echo ""
wscript.echo "Operation complete.  See Log:  " & strLogFileName



'Close logfile
oLogFile.close


Sub Output(txt)
	wscript.echo txt
	oLogFile.writeLine txt
End Sub


Sub GetGroups(strUserDN,strUserSID,strDNSdomain)
	
	
	Const ADS_SCOPE_SUBTREE = 2
	
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	Set adoCommand.ActiveConnection = adoConnection
	
	Set objRootDSE = GetObject("LDAP://" & strDNSdomain & "/RootDSE")
	strRootDSE = objRootDSE.Get("defaultNamingContext")

	
	strForeignSID="CN=" & strUserSID & ",CN=ForeignSecurityPrincipals," & strRootDSE
	
	strBase = "<LDAP://" & strDNSdomain & "/" & strRootDSE & ">"
	
	strFilter = "(&(objectCategory=group)(|(member=" & strUserDN & ")(member=" & strForeignSID & ")))"
	
	strAttributes = "CN,ADsPath"
	
	strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
	adoCommand.CommandText = strQuery
	adoCommand.Properties("Page Size") = 1000
	adoCommand.Properties("Timeout") = 30
	adoCommand.Properties("Cache Results") = False
	
	Set adoRecordset = adoCommand.Execute
	
	Do Until adoRecordset.EOF
		strCN = adoRecordset.Fields("CN").Value
		strADsPath = adoRecordset.Fields("ADsPath").value
	
		'Eliminate duplicates
		AddMe=True
		arrGroups=split(oDict(strUserDN),";")
		For each grp in arrGroups
			If grp=strCN then AddMe=False
		Next
		
		If AddMe=True then oDict(strUserDN)=oDict(strUserDN) & strCN & ";"
			
		adoRecordset.MoveNext
		strCN=""
		strADsPath=""
	Loop
	
	adoRecordset.Close
	adoConnection.Close

End Sub



Function OctetToHexStr(arrbytOctet) 
	' Function to convert OctetString (byte array) to Hex string. 
	
	Dim k 
	OctetToHexStr = "" 
	For k = 1 To Lenb(arrbytOctet) 
	OctetToHexStr = OctetToHexStr _ 
	& Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2) 
	Next 
End Function 
	
Function HexStrToDecStr(strSid) 
	on error resume next
	' Function to convert hex Sid to decimal (SDDL) Sid. 
	Dim arrbytSid, lngTemp, j 
	
	ReDim arrbytSid(Len(strSid)/2 - 1) 
	For j = 0 To UBound(arrbytSid) 
	arrbytSid(j) = CInt("&H" & Mid(strSid, 2*j + 1, 2)) 
	Next 
	
	HexStrToDecStr = "S-" & arrbytSid(0) & "-" _ 
	& arrbytSid(1) & "-" & arrbytSid(8) 
	
	lngTemp = arrbytSid(15) 
	if err.number <> 0 then 
		msgbox err.number & vbcrlf & err.description & vbCrLf & strSid
		wscript.quit
	end if
	lngTemp = lngTemp * 256 + arrbytSid(14) 
	lngTemp = lngTemp * 256 + arrbytSid(13) 
	lngTemp = lngTemp * 256 + arrbytSid(12) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(19) 
	lngTemp = lngTemp * 256 + arrbytSid(18) 
	lngTemp = lngTemp * 256 + arrbytSid(17) 
	lngTemp = lngTemp * 256 + arrbytSid(16) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(23) 
	lngTemp = lngTemp * 256 + arrbytSid(22) 
	lngTemp = lngTemp * 256 + arrbytSid(21) 
	lngTemp = lngTemp * 256 + arrbytSid(20) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(25) 
	lngTemp = lngTemp * 256 + arrbytSid(24) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 

End Function

Sub GetGroups2(strUserDN,strDNSdomain)
	ON ERROR RESUME NEXT
	
	Set oUser=GetObject("LDAP://" & strDNSdomain & "/" & strUserDN)
	arrGroups=oUser.memberOf

	For each grp in arrGroups
		oDict(strUserDN)=oDict(strUserDN) & grp & ";"
		'You can comment this next line out...
		wscript.echo "GROUP LOCAL TO OU:  " & grp
	Next
		
End Sub

Open in new window

0
 
bsharathAuthor Commented:
Both did not work... Sorry for the trouble
The local group that i mention is where i have all users
the groups are both in root and another child domain. Should i mention the 2nd shild domain next to the Local domain?
strLocalDomain="dev.group.co.uk,EU.group.co.uk"
0
 
jostranderCommented:
No, just 1 domain in strLocalDomain.  Do you get any output at all?  Any errors?  Do you see any lines that say "GROUP LOCAL TO OU" in the cmd window?  
Any results you get could help a lot.

Here is how I am testing:
strOU="OU=TEST,DC=testlab,DC=local"
strLocalDomain="testlab.local"
strRemoteDomainList="child.testlab.local,testlab2.local"

Notes:
1) OU=TEST,DC=testlab,DC=local exists in the root domain and is the OU with my users in it
2) testlab.local is my root domain
3) child.testlab.local is a child domain of testlab.local
4) testlab2.local is a trusted domain in a separate forest (added to verify that this works that way as well)
5) all 3 domains contain groups that have the user accounts from testlab.local (OU=TEST,DC=testlab,DC=local) in at least 1 group (all report successfully in the results)

Please review and see if my test is similar to yours.  Thanks :)


I am logged into the domain controller on the root domain testlab.local.
0
 
bsharathAuthor Commented:
I get data as this

GROUP LOCAL TO OU:
Bala.plc.com@HasBeenMigratedTo.Exchange2007;;Son Off- iCP
GROUP LOCAL TO OU:  CN=Lo-MS Blds-SGR,OU=Security Groups,OU=ID,OU=Countries,DC=Development,DC=Group,DC=co,DC=uk
Development is a child domain
EUI is another child domain
Group.co.uk is the root Domain
All in same forest
3 Child Domains and 1 root Domain

But i want to query only 2 so mentioned only 2 domain names
0
 
bsharathAuthor Commented:
Now the group.co.uk is the data thats missings
i have my major groups there thats the root Domain
0
 
jostranderCommented:
Here's a test that should do just the root domain... I'm curious as to the output
'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"

'DNS domain name
strLocalDomain="group.co.uk"

'------------------------------------------------

Set WshShell=CreateObject("Wscript.Shell")
Set oDict=CreateObject("Scripting.Dictionary")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If


'Find users in OU
Set objOU = GetObject("LDAP://" & strLocalDomain & "/" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 

		strDN=objUser.DistinguishedName
		strMail=objUser.mail
		
		If strMail<>"" then 
			oDict.Add strDN,objUser.mail & ";"
		Else
			oDict.Add strDN,objUser.sAMAccountName & "@" & strLocalDomain & ";"
		End If
		
		GetGroups2 strDN,strLocalDomain
	End If
Next		

For each key in oDict.keys
	wscript.echo oDict(key)
Next



Sub GetGroups2(strUserDN,strDNSdomain)
	ON ERROR RESUME NEXT
	
	Set oUser=GetObject("LDAP://" & strDNSdomain & "/" & strUserDN)
	arrGroups=oUser.memberOf

	For each grp in arrGroups
		oDict(strUserDN)=oDict(strUserDN) & grp & ";"
	Next
		
End Sub

Open in new window

0
 
bsharathAuthor Commented:
Still does not fetch the root domain groups
ID: 31162860 this slow version works
0
 
jostranderCommented:
Ohhhhh, when you said previous script worked, I didn't realize you meant that one.  

Please try this:
'------------------------------------------------
'	User Variables
'------------------------------------------------
'Name of OU to search for users
strOU="OU=Countries,DC=Group,DC=co,DC=uk"

'Name of your logfile
strLogFileName="D:\GroupMembership.txt"

'List of DNS Domains,separated by comma
strDNSdomainList="group.co.uk,de.group.co.uk,eoi.group.co.uk"

'------------------------------------------------


Set WshShell=CreateObject("Wscript.Shell")
Set oDict=CreateObject("Scripting.Dictionary")

'Force CSCRIPT
If instr(lcase(wscript.fullname),"wscript") then
	wshshell.run "cmd /k cscript //nologo " & chr(34) & wscript.scriptfullname & Chr(34),1,false
	wscript.quit
End If

Set fso = CreateObject("scripting.filesystemobject") 
Set oFile = fso.OpenTextFile(strLogFileName,2,true)

arrDomains=split(strDNSdomainList,",")

'Make dictionary of users in OU
Set objOU = GetObject("LDAP://" & strOU)
For each objUser in objOU 
	If objUser.Class = "user" then 
		strSAM=""
		strMail=""
		strSidDec=""
		strSidHex=""
		arrSid=""
		
		'Get the user SID
		arrSid = objUser.objectSid 
		strSidHex = OctetToHexStr(arrSid) 
		strSidDec = HexStrToDecStr(strSidHex)
		
		strDN=objUser.DistinguishedName
		strMail=objUser.mail
		
		oDict.Add strDN,strMail & ";"
		For each strDomain in arrDomains
			GetGroups strDN,strSidDec,strDomain
		Next
	End If
Next





For each key in oDict.Keys
	oFile.WriteLine oDict(key)
	wscript.echo oDict(key)
Next

oFile.close

wscript.echo
wscript.echo "Operation Complete."
wscript.echo "See logfile:  " & strLogFileName

Sub GetGroups(strUserDN,strUserSID,strDNSdomain)

	Const ADS_SCOPE_SUBTREE = 2
	
	Set objRootDSE = GetObject("LDAP://" & strDNSdomain & "/rootDSE")
	strRootDSE = objRootDSE.Get("defaultNamingContext")
	
	strADsPath=""
	strADsPath="LDAP://" & strDNSdomain & "/" & strRootDSE


	strForeignSID="CN=" & strUserSID & ",CN=ForeignSecurityPrincipals," & strRootDSE
	

	Set objConnection = CreateObject("ADODB.Connection")
	Set objCommand =   CreateObject("ADODB.Command")
	objConnection.Provider = "ADsDSOObject"
	objConnection.Open "Active Directory Provider"
	Set objCommand.ActiveConnection = objConnection
	
	objCommand.Properties("Page Size") = 1000
	objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
	
	objCommand.CommandText = _
		"SELECT ADsPath,CN FROM '" & strADsPath & "' WHERE objectCategory='group' and (member='" & strUserDN & "' or member='" & strForeignSID & "')"
	
	Set objRecordSet = objCommand.Execute
	
	If NOT objRecordSet.EOF then objRecordSet.MoveFirst

	While NOT objRecordSet.EOF
		strADsPath_group=""
		strADsPath_group= objRecordSet.Fields("ADsPath").value
		strGroupCN=""
		strGroupCN= objRecordSet.Fields("CN").value

		'Eliminate duplicates
		AddMe=True
		arrGroups=split(oDict(strUserDN),";")
		For each grp in arrGroups
			If grp=strGroupCN then AddMe=False
		Next
		
		If AddMe=True then oDict(strUserDN)=oDict(strUserDN) & strGroupCN & ";"
		'If AddMe=True then oDict(strUserDN)=oDict(strUserDN) & strDNSdomain & "\" & strGroupCN & ";"

		objRecordSet.MoveNext
		strGroupCN=""
	Wend
	
	Set objConnection=Nothing
	Set objCommand=Nothing
	Set objRecordSet=Nothing
End Sub


Function OctetToHexStr(arrbytOctet) 
	' Function to convert OctetString (byte array) to Hex string. 
	
	Dim k 
	OctetToHexStr = "" 
	For k = 1 To Lenb(arrbytOctet) 
	OctetToHexStr = OctetToHexStr _ 
	& Right("0" & Hex(Ascb(Midb(arrbytOctet, k, 1))), 2) 
	Next 
End Function 
	
Function HexStrToDecStr(strSid) 
	on error resume next
	' Function to convert hex Sid to decimal (SDDL) Sid. 
	Dim arrbytSid, lngTemp, j 
	
	ReDim arrbytSid(Len(strSid)/2 - 1) 
	For j = 0 To UBound(arrbytSid) 
	arrbytSid(j) = CInt("&H" & Mid(strSid, 2*j + 1, 2)) 
	Next 
	
	HexStrToDecStr = "S-" & arrbytSid(0) & "-" _ 
	& arrbytSid(1) & "-" & arrbytSid(8) 
	
	lngTemp = arrbytSid(15) 
	if err.number <> 0 then 
		msgbox err.number & vbcrlf & err.description & vbCrLf & strSid
		wscript.quit
	end if
	lngTemp = lngTemp * 256 + arrbytSid(14) 
	lngTemp = lngTemp * 256 + arrbytSid(13) 
	lngTemp = lngTemp * 256 + arrbytSid(12) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(19) 
	lngTemp = lngTemp * 256 + arrbytSid(18) 
	lngTemp = lngTemp * 256 + arrbytSid(17) 
	lngTemp = lngTemp * 256 + arrbytSid(16) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(23) 
	lngTemp = lngTemp * 256 + arrbytSid(22) 
	lngTemp = lngTemp * 256 + arrbytSid(21) 
	lngTemp = lngTemp * 256 + arrbytSid(20) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 
	
	lngTemp = arrbytSid(25) 
	lngTemp = lngTemp * 256 + arrbytSid(24) 
	
	HexStrToDecStr = HexStrToDecStr & "-" & CStr(lngTemp) 

End Function

Open in new window

0
 
bsharathAuthor Commented:
Thanks a lot jostrander
works fast and perfect
:-)
Rob thank you too...
if time permits please have a look at my other posts...
0
 
jostranderCommented:
Glad I could help... sorry it took so many tries :D

This will be useful to me at my workplace too, so it was a great project.

Thanks,
Joe
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.

Join & Write a Comment

Featured Post

Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

  • 21
  • 21
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now