VBscript: VBscript to enumerate all groups and their members from a specific Active Directory OU

Posted June 1st, 2011 in groups by dirk adamsky

Today’s script is made for Tyrone.

His question was a script that enumerates all groups and their members from a given OU.
I already had a script that enumerates the members of an OU.
I also had a script that enumerates the members of a nested group (uses recursion).
The 2 scripts combined are the solution for Tyrone.

Follow the next steps to run the script (no admin rights needed):

* open your favorite text editor
* copy and paste the script into the editor
* change the OU distinguished name (in line 7) into your OU distinguished name
* save the script (for example c:\temp\EnumerateGroupsInOu.vbs)
* open a command prompt
* go to “c:\temp”
* give “cscript EnumerateGroupsInOu.vbs” (without quotes) and enter

You can also dump the output to a file:

* give “cscript EnumerateGroupsInOu.vbs > EnumerateGroupsInOu.txt” (without quotes) and enter

To get that file into Excel:

* open Excel
* go to Menu=>Open File
* change file type to “all”
* chose EnumerateGroupsInOu.txt
* chose “;” as separator character

The script:

' Name : EnumerateGroupsInOu.vbs
' Description : script to enumerate all groups and their members from a specific Active Directory OU
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 01-06-2011

Set objOU = GetObject("LDAP://OU=test,DC=test,DC=org")
	For Each objMember in objOU
		If (LCase(objMember.Class) = "group") Then
			EnumNestedgroup objMember.AdsPath
		End If
	Next
Set objOU = Nothing

Function EnumNestedgroup(strGroupDN)
	Set objGroup = GetObject(strGroupDN)
	For Each objMember in objGroup.Members
		If (LCase(objMember.Class) = "group") Then
			wscript.echo objMember.AdsPath
			EnumNestedgroup objMember.AdsPath
		Else
			Wscript.Echo objGroup.Name & " ; " & objMember.DisplayName & " ; " & objMember.Mail &_
			" ; " & objMember.Department &  " ; " &	objMember.Company & " ;  " & objMember.Title
		End If
	Next
	Set objGroup = Nothing
End Function

When you have problems/questions with the script please post a reply.

Happy scripting.

Best regards,

Dirk Adamsky

Active Directory: VBscript to enumerate the message restrictions (send to rights) of a user or distributiongroup v2

Posted August 20th, 2010 in messagerestrictions by dirk adamsky

Suffering from a lack of inspiration I decided to rework a previous script.
I had a request on my previous messagerestriction script.
Added to the script is the option to enter the smtp address of
the user or group object for which the messagerestrictions are set.
I have done that by re-using code from this script.
Another question was the option to output to a file,
this can be done easily by running the script like this:

cscript enumeratesendtorights.vbs > thefilenameofyourchoice.txt.

Follow the next steps to run the script (no admin rights needed):

* find the distinguished name of the nested group (adsiedit.msc)
* open your favorite text editor
* copy and paste the script into the editor
* change the distinguished name
* save the script (for example c:tempenumeratesendtorights.vbs)
* open a command prompt
* go to “c:temp”
* give “cscript enumeratesendtorights.vbs” (without quotes) and enter

The script:

' Name : enumeratesendtorights.vbs
' Description : script to enumerate the message restrictions (send to rights) of a distributionlist
' Author : dirk adamsky - deludi bv
' Version : 2.00 added smtp input option based on input from M (see comments on previous script)
' Date : 20-08-2010 (v.1.00 date 08-02-2010)
' Level: advanced

strObject = InputBox("Please enter the smtp address")
Set objSource = GetObject("LDAP://" & GetDN(strObject))
If TypeName(objSource.authOrig) = "String" Then
	GetSendToRights ("LDAP://" & objSource.authOrig)
Else
	For Each User In objSource.authOrig
		GetSendToRights ("LDAP://" & User)
	Next
End If
If TypeName(objSource.dLMemSubmitPerms) = "String" Then
	EnumNestedgroup objSource.dLMemSubmitPerms
Else
	For Each Group in objSource.dLMemSubmitPerms
		EnumNestedgroup Group
	Next
End If
Set objSource = Nothing

Function GetDN(strMail)
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	adoCommand.ActiveConnection = adoConnection
	Set objRootDSE = GetObject("LDAP://RootDSE")
	strBase = "<LDAP://" & objRootDSE.Get("defaultNamingContext") & ">"

	' Filter on user objects.
	strFilter = "(mail=" &  strMail & ")"

	' Comma delimited list of attribute values to retrieve.
	strAttributes = "distinguishedName"

	' 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
	Set adoRecordset = adoCommand.Execute
	wscript.echo adoRecordset.Fields("distinguishedName").Value
	GetDN = adoRecordset.Fields("distinguishedName").Value
	adoRecordset.Close
	adoConnection.Close

	Set adoRecordset = Nothing
	Set objRootDSE = Nothing
	Set adoConnection = Nothing
	Set adoCommand = Nothing

End Function

Function GetSendToRights(strUserDN)
	On Error Resume Next
	Set objAccount = GetObject(strUserDN)
	Wscript.Echo objAccount.Mail & " ; " & objAccount.DisplayName & " ; direct send to rights"
	Set objSecurityDescriptor = objAccount.Get("ntSecurityDescriptor")
	Set objDacl = objSecurityDescriptor.DiscretionaryAcl
	Set objAce = CreateObject("AccessControlEntry")
	For Each objAce In objDacl
		If objAce.ObjectType = "{AB721A54-1E2F-11D0-9819-00AA0040529B}" Then
			If (Left(objAce.Trustee,3) <> "S-1" And objAce.Trustee <> "NT AUTHORITYSELF") Then
				GetUserDetails Mid(objAce.Trustee,9)
			End If
		End If
	Next
End Function

Function GetUserDetails(strPreW2K)
	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 & ">"

	' Filter on user objects.
	strFilter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" &  strPreW2K & "))"

	' Comma delimited list of attribute values to retrieve.
	strAttributes = "mail, displayname"

	' 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
	Wscript.Echo adoRecordset.Fields("mail").Value & " ; " & adoRecordset.Fields("displayname").Value & " ; indirect send to rights"
	' Clean up.
	adoRecordset.Close
	adoConnection.Close

	Set adoRecordset = Nothing
	Set objRootDSE = Nothing
	Set adoConnection = Nothing
	Set adoCommand = Nothing
End Function	

Sub EnumNestedgroup(strGroupDN)
	Set objGroup = GetObject("LDAP://" & strGroupDN)
	For Each objMember in objGroup.Members
		If (LCase(objMember.Class) = "group") Then
			Call EnumNestedgroup(objMember.AdsPath)
		Else
			GetSendToRights objMember.AdsPath
		End If
	Next
	Set objGroup = Nothing
End Sub

When you have problems/questions with the script please post a reply.

Happy scripting.

Best regards,

Dirk Adamsky

Active Directory: VBscript to enumerate the members of remote desktop users group of all servers

Posted April 23rd, 2010 in active directory, remotedesktopusers, vbscript by dirk adamsky

Script for today is about members of the remote desktop users local group.
This group exists on all servers except the domain controllers.
The script can take a long time in large domains because it connects each server separately.

Follow the next steps to run the script (admin rights needed):

  • copy and paste the script in your favorite text editor
  • save the script (for example c:tempremotedesktopusers.vbs)
  • open a command prompt
  • go to “c:temp”
  • give “cscript remotedesktopusers.vbs” (without quotes) and enter

The script:

' Name : remotedesktopusers.vbs
' Description : script to enumerate the members of remote desktop users group of all servers
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 23-04-2010
' Level: intermediate

Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
strBase = "<LDAP://" & strDNSDomain & ">"

strFilter = "(&(objectCategory=computer)(operatingSystem=*server*))"

strAttributes = "name,distinguishedName"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute

Do Until adoRecordset.EOF
	strHostname = adoRecordset.Fields("name").Value
	If CheckStatus(strHostname) = True Then
		If Instr(adoRecordset.Fields("distinguishedName").Value,"Domain Controllers") = 0 Then
			Set objGroup = GetObject("WinNT://" & strHostname & "/Remote Desktop Users,group")
			For Each Member In objGroup.Members
				wscript.echo strHostname & " has " & Member.Name & " in the remote desktop users group"
			Next
			Set objGroup = Nothing
		End If
	End If
	adoRecordset.MoveNext
Loop

adoRecordset.Close
adoConnection.Close

Set adoRecordset = Nothing
Set objRootDSE = Nothing
Set adoConnection = Nothing
Set adoCommand = Nothing

Function CheckStatus(strAddress)
	Dim objPing, objRetStatus
	Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
      ("select * from Win32_PingStatus where address = '" & strAddress & "'")
	For Each objRetStatus In objPing
        If IsNull(objRetStatus.StatusCode) Or objRetStatus.StatusCode <> 0 Then
			CheckStatus = False
        Else
			CheckStatus = True
        End If
    Next
	Set objPing = Nothing
End Function

When you have problems/questions please post a reply or give a ‘star’ rating.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

Active Directory: VBscript to count the number of users in subgroups of a nested distribution group

Posted March 30th, 2010 in distributiongroups by dirk adamsky

Last friday I got a question from Marten on the number of users that a subgroup contains.
I have made a small mutation of the previous script to achieve this. The output of the script now contains the number of users in each subgroup.

Follow the next steps to run the script (no admin rights needed):

  • open your favorite text editor
  • copy and paste the script into the editor
  • save the script (for example c:tempcountgroupmembershipnestedgroup.vbs)
  • open a command prompt
  • go to “c:temp”
  • give “cscript countgroupmembershipnestedgroup.vbs” (without quotes) and enter

The script:

' Name : countgroupmembershipnestedgroup.vbs
' Description : script to count the number of users in subgroups of a nested distribution group
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 30-03-2010
' Level : intermediate

Set objDictionary = CreateObject("Scripting.Dictionary")
strTargetGroupDN = "LDAP://CN=SW (Alle Medewerkers),OU=DistributieGroepen,OU=Groepen,DC=domstad,DC=org"
Call EnumNestedgroup(strTargetGroupDN)

Sub EnumNestedgroup(strGroupDN)
	Set objGroup = GetObject(strGroupDN)
	For Each objMember in objGroup.Members
		If (LCase(objMember.Class) = "group") Then
			Call EnumNestedgroup(objMember.AdsPath)
		Else
			If objDictionary.Exists(objGroup.DisplayName) Then
				objDictionary.Item(objGroup.DisplayName) = objDictionary.Item(objGroup.DisplayName) + 1
			Else
				objDictionary.Add objGroup.DisplayName, 1
			End If
		End If
	Next
	Set objGroup = Nothing
End Sub

For Each strKey in objDictionary.Keys
	If objDictionary.Item(strKey) > 1 Then
		Wscript.Echo strKey & " contains ; " & objDictionary.Item(strKey) & " ; users"
	End If
Next

Set objDictionary = Nothing

When you have problems/questions please post a reply.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV
[adrotate group="1"]