Skip to main content

vbScript - List All Members Of Sensitive Groups: Schema, Enterprise and Domain Admins

·4 mins

Update 2011.06.21: I found a missing line in this script keeping it from running. I fixed that in the code below. I also added a downloadable zip file with the script to help with the formatting issues caused when copying and pasting directly from the site.

Update 2009.04.16: At the request of a commenter, I added a couple lines to the script that will dump the output to a text file in the root of the C: drive. I also corrected a couple errors in the script.

I was tasked to get a dump of all the users in our Schema Admins, Enterprise Admins and Domain Admins for our Forest. I started thinking about it and realized a couple things. Two of the three groups reside at the forest root while the Domain Admins group exists for every domain in the forest. This meant I would need to enumerate every domain and depending on the domain, enumerate either all three groups or just one.

My thinking was overly complex and I realized this halfway through writing a new script. Using the power of LDAP, I can use a logical “or” (|) statement. When run against a domain, it would always return “Domain Admins” since it will always exist in an AD domain. When it is run against the forest root domain, it would also return the “Enterprise Admins” group and “Schema Admins” group. Here is the LDAP query:

(&(objectCategory=group)(|((name=Enterprise Admins*)(name=Domain Admins*)(name=Schema Admins*))))

At this point, all I need to do is this:

  1. Enumerate all domains in the forest
  2. Loop through each domain
  3. Execute LDAP query against each domain
  4. Loop through LDAP query results
  5. Dump membership of each group

The script below does just that. I hope some find it useful. There is no configuration necessary. You should be able to just run it from your environment as no domain references (or really anything) is hard coded. The only thing you may want to add to or remove from is the LDAP filter. Cheers!

'==========================================================================
' VBScript Source File
' NAME   : Active Directory Admin Audit
' AUTHOR : Andrew J Healey
' DATE   : 2009.04.16
' UPDATED: 2011.06.21
' USAGE  : cscript /nologo AD-AdminAudit.vbs
' COMMENT: This script will check all the domains within a forest
'		and report all the members of the following groups: Schema
'		Admins, Enterprise Admins and Domain Admins. See notes to
'		expand on the groups.
'==========================================================================

Option Explicit

'Define Constants
Const adUseClient = 3
Const ForWriting = 2

'Set the path and filename for the dump of sensitive users
'  Folder must exist!
Dim fileTemp : fileTemp = "C:\Temp\AD Admin Audit.txt"

' Create tmp file and report file
Dim objFSO, objTempFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTempFile = objFSO.OpenTextFile(fileTemp, ForWriting, True)

' Query RootDSE and return array with all AD domains in forest
Dim adoCommand, adoConnection, objRootDSE
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.cursorLocation = adUseClient
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
Set objRootDSE = GetObject("LDAP://RootDSE")

' Build the LDAP Query
Dim strBase, strFilter, strAttrs, strScope, strQuery
strBase   =  ";"
strFilter = "(objectcategory=domainDNS);"
strAttrs  = "distinguishedName;"
strScope  = "subtree"
strQuery = strBase & strFilter & strAttrs & strScope

' Set Query parameters
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 50
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

' Execute the query
Dim adoRecordSet : Set adoRecordSet = adoCommand.Execute

' Start Loop
Do Until adoRecordSet.EOF
	' Parse ad search results to create well formed DNS domain
	Dim strDomain
	strDomain = Replace(adoRecordSet.Fields(0).Value,"DC=","")
	strDomain = Replace(strDomain,",",".")
	Call GrpAll(strDomain)
	adoRecordSet.MoveNext
Loop
adoRecordSet.Close
adoConnection.Close

Private Function GrpAll(byVal strDomain)
	' To search for more groups, edit the "strFilter" line. It uses a simple
	'  LDAP or (|) so multiple groups can be added. It uses ADO record sets
	'  to loop so it doesn't have to find all of them, just one. Every domain
	'  will contain at least the Domain Admins group.
	Dim adoComm, adoConn
	Set adoComm = CreateObject("ADODB.Command")
	Set adoConn = CreateObject("ADODB.Connection")
	adoConn.Provider = "ADsDSOObject"
	adoConn.cursorLocation = adUseClient
	adoConn.Open "Active Directory Provider"
	adoComm.ActiveConnection = adoConn
	
	strBase   = ";"
	strFilter = "(&(objectCategory=group)(|((name=Enterprise Admins*)(name=Domain Admins*)(name=Schema Admins*))));"
	strAttrs  = "name,member;"
	strScope  = "subtree"
	
	strQuery = strBase & strFilter & strAttrs & strScope
	adoComm.CommandText = strQuery
	adoComm.Properties("Page Size") = 5000
	adoComm.Properties("Timeout") = 30
	adoComm.Properties("Cache Results") = False
	
	Dim adoRS : Set adoRS = adoComm.Execute
	
	objTempFile.WriteLine "Group report for domain: " & strDomain
	
	adoRS.MoveFirst
	
	Do Until adoRS.EOF
		Dim strMember
		objTempFile.WriteLine vbTab & adoRS.Fields(0).Value
		For Each strMember in adoRS.Fields(1).Value
			objTempFile.WriteLine vbTab & vbTab & strMember
		Next
		adoRS.MoveNext
	Loop
	
	adoRS.Close
	adoConn.Close
End Function

Related

SNMP In A Windows Environment

·2 mins
The difficult part with managing SNMP via Group Policy is that SNMP is not installed by default. The first step is to install SNMP on all the machines you want to monitor via SNMP. This can be managed a couple ways. The simplest method that I have used is the one Zenoss recommends. If you only have a couple of machines to install SNMP on, it may be easier just to go into the Add/Remove Programs –> Add/Remove Windows Components –> Management and Monitoring Tools –> Simple Network Monitoring Protocol.

List All User Object Attributes in Active Directory Schema.. Whew!

·2 mins
Here is a little script I put together for one of our developers here at work. Feel free to use, abuse, change, tweak, fix, etc. '* Script name: List All Attributes.vbs '* Created on: 01/28/2009 '* Author: Andrew J Healey '* Purpose: Exports all attributes from the user object type within '* the Active Directory schema. '* Usage: cscript /nologo "list all attributes.vbs" > Attributes.csv '* History: Andrew J Healey 01/28/2009 '* - Created script ' Option Explicit 'Declarations Dim objUserClass : Set objUserClass = GetObject("LDAP://schema/user") Dim objSchemaClass : Set objSchemaClass = GetObject(objUserClass.Parent) wscript.echo chr(34) & "Mandatory" & chr(34) & "," & _ chr(34) & "Name" & chr(34) & "," & _ chr(34) & "Syntax" & chr(34) & "," & _ chr(34) & "Single/Multi Valued" & chr(34) Call GetAttributes(objUserClass.MandatoryProperties,objSchemaClass,True) Call GetAttributes(objUserClass.OptionalProperties,objSchemaClass,False) Private Sub GetAttributes(x,y,z) Dim strAttribute 'Loop through all attributes For Each strAttribute in x Dim strOut : strOut = "" 'Compares whether the attribute is mandatory or optional 'Prints whether mandatory/optional and name of attribute If z = True then strOut = strOut & chr(34) & "Yes" & chr(34) & "," & _ chr(34) & strAttribute & chr(34) & "," Else strOut = strOut & chr(34) & "No" & chr(34) & "," & _ chr(34) & strAttribute & chr(34) & "," End If 'Get the attributes syntax: i.e. Integer, String, NumericString, etc. Dim objAttribute : Set objAttribute = y.GetObject("Property", strAttribute) strOut = strOut & chr(34) & objAttribute.Syntax & chr(34) & "," 'Determines whether column holds multi or single values If objAttribute.MultiValued Then strOut = strOut & chr(34) & "Multi" & chr(34) Else strOut = strOut & chr(34) & "Single" & chr(34) End If 'Print string to screen. Each line its own CSV. wscript.echo strOut strOut = Empty Next Set objAttribute = Nothing strAttribute = Empty End Sub

VBScript: Delete Files Older Than One Hour

·2 mins
So, I am constantly looking for ways of automating tasks. Too many admins do not take advantage of scripting and scheduled tasks/cron. Just this last week, I was implementing a new print server. Besides just building up the new server, I wanted to actually offer the users something new and useful. I’ve been wanting to setup a network pdf printer for quite some time. I have played around with setting up a network PDF printer using cups. However, we seem to be so MS centric these days that I decided to use PDFCreator’s print server. It was really a piece of cake. Just install the server portion, setup the service, create a share and watch the PDF’s spool.