Running a Windows NT Domain / Active Directory Audit

Getting an audit of your IT environment is incredibly useful. When you consider an audit from a security perspective – in the Windows NT domain or Active Directory model – there are a few items of significant importance: domains, users, groups, computers, and services.

The first step in conducting an audit is discovery – find out what’s out there. Fortunately, we have a great scripting tool for this: ADSI (Active Directory Services Interface). ADSI can pull the information for us, but to utilize it, we need to store it somewhere – such as in a SQL database.

To save you the trouble of figuring this out, below is a (rather long) script which uses ADSI to poll your network and store data into text files. To run it successfully, you must have at least query access to your entire directory. (The script has been tested on an NT 4.0 domain and on an Active Directory site.) The script queries each domain, obtaining all users, groups (including group memberships), and computers; and for each computer, obtains all local users, groups (and group memberships), and services. The output is saved into pipe-delimited text files for easy import into a database.

The script, which I save as netquery.vbs, has the following syntax:

cscript.exe netquery.vbs [nodomainusers] [nodomaingroups] [nocomputers] [nolocalusers] [nolocalgroups] [noservices]

nodomainusers    Suppresses querying of domain users and groups
nodomaingroups   Suppresses querying of domain groups
nocomputers      Suppresses querying of computers, local users and groups, and services
nolocalusers     Suppresses querying of local users and groups
nolocalgroups    Suppresses querying of local groups
noservices       Suppresses querying of services

The script generates text files in the current directory. Note that existing files will be overwritten! Each text file has a header as its first row. Import each text file into a database table with the exact same name. References between tables is logical if you look at the column names. Each object has an ADSPath, which is unique. Objects may reference an ADSOwner, which is the object’s parent (such as the domain or computer for which a user or group belongs, or the computer which a service is installed on). One special file exists – the groupmembers file. This has only two fields – ADSOwner and ADSMember – which are used to correlate the group (ADSOwner) with its many members (ADSMember).

Play around with it and it’ll make sense. If your network is huge, this will take a long time to run! You can tell things are working if data is being added to the output files.

And now, with no further delays, is the master script: netquery.vbs!

Option Explicit

On Error Resume Next

Const ForWriting = 2

'ARGUMENTS
Dim blnDomainUsers, blnDomainGroups, blnComputers, blnLocalUsers, blnLocalGroups, blnServices

blnDomainUsers = True
blnDomainGroups = True
blnComputers = True
blnLocalUsers = True
blnLocalGroups = True
blnServices = True
For Each item In WScript.Arguments
	Select Case LCase(item)
		Case "nodomainusers" 
			blnDomainUsers = False
			blnDomainGroups = False
		Case "nodomaingroups"
			blnDomainGroups = False
		Case "nocomputers"
			blnComputers = False
			blnLocalUsers = False
			blnLocalGroups = False
			blnServices = False
		Case "nolocalusers"
			blnLocalUsers = False
			blnLocalGroups = False
		Case "nolocalgroups"
			blnLocalGroups = False
		Case "noservices"
			blnServices = False
	End Select
Next

'CREATE FILESYSTEMOBJECT
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")

Dim objDomainsFile, objUsersFile, objGroupsFile, objGroupMembersFile, objComputersFile, objServicesFile
Set objDomainsFile = objFSO.OpenTextFile("domains.txt", ForWriting, True)
Set objUsersFile = objFSO.OpenTextFile("users.txt", ForWriting, True)
Set objGroupsFile = objFSO.OpenTextFile("groups.txt", ForWriting, True)
Set objGroupMembersFile = objFSO.OpenTextFile("groupmembers.txt", ForWriting, True)
Set objComputersFile = objFSO.OpenTextFile("computers.txt", ForWriting, True)
Set objServicesFile = objFSO.OpenTextFile("services.txt", ForWriting, True)

objDomainsFile.WriteLine "adspath|name"
objUsersFile.WriteLine "adspath|adsowner|name|fullname|description|passwordage|lastlogin|lastlogoff|raspermissions|accountdisabled"
objGroupsFile.WriteLine "adspath|adsowner|name"
objGroupMembersFile.WriteLine "adsowner|adsmember"
objComputersFile.WriteLine "adspath|adsowner|name|passwordage|owner|division|operatingsystem|osversion|processor|processorcount"
objServicesFile.WriteLine "adspath|adsowner|name|displayname|account"

Dim objDomains, objDomain, objUsers, objUser, objGroups, objGroup
Dim objComputers, objComputer, objComputerAccount, objServices, objService
Dim s1, s2, s3, s4, s5, s6, s7, obj, cls, op, item

Set objDomains = GetObject("WinNT:")

For Each objDomain in objDomains
	objDomainsFile.Write objDomain.AdsPath
	objDomainsFile.Write "|"
	objDomainsFile.Write objDomain.Name
	objDomainsFile.WriteLine
	
	'DOMAIN USERS
	If blnDomainUsers Then
		Set objUsers = Nothing
		Set objUser = Nothing
		Set objUsers = GetObject(objDomain.AdsPath)
		objUsers.Filter = Array("User")

		For Each objUser in objUsers
			objUsersFile.Write objUser.AdsPath
			objUsersFile.Write "|"
			objUsersFile.Write objDomain.AdsPath
			objUsersFile.Write "|"
			objUsersFile.Write objUser.Name
			objUsersFile.Write "|"
			objUsersFile.Write objUser.FullName
			objUsersFile.Write "|"
			objUsersFile.Write objUser.Description
			objUsersFile.Write "|"
			objUsersFile.Write objUser.PasswordAge
			objUsersFile.Write "|"
			objUsersFile.Write objUser.LastLogin
			objUsersFile.Write "|"
			objUsersFile.Write objUser.LastLogoff
			objUsersFile.Write "|"
			objUsersFile.Write objUser.RasPermissions
			objUsersFile.Write "|"
			If objUser.UserFlags And &H0002 Then 
				objUsersFile.Write "1"
			Else 
				objUsersFile.Write "0"
			End If
			objUsersFile.WriteLine
		Next
	End If
	
	'DOMAIN GROUPS
	If blnDomainGroups Then
		Set objGroups = Nothing
		Set objGroup = Nothing
		Set objGroups = GetObject(objDomain.AdsPath)
		objGroups.Filter = Array("Group")

		For Each objGroup in objGroups
			objGroupsFile.Write objGroup.AdsPath 
			objGroupsFile.Write "|"
			objGroupsFile.Write objDomain.AdsPath
			objGroupsFile.Write "|"
			objGroupsFile.Write objGroup.Name
			objGroupsFile.WriteLine

			For Each objUser In objGroup.Members
				If Right(objUser.Name, 1) <> "$" Then
					objGroupMembersFile.Write objGroup.AdsPath
					objGroupMembersFile.Write "|"
					objGroupMembersFile.Write objUser.AdsPath
					objGroupMembersFile.WriteLine
				End If
			Next
		Next
	End If
	
	'COMPUTERS
	If blnComputers Then
		Set objComputers = Nothing
		Set objComputer = Nothing
		Set objComputers = GetObject(objDomain.AdsPath)
		objComputers.Filter = Array("Computer")

		For Each objComputer in objComputers
			Set objComputerAccount = GetObject(objComputer.AdsPath & "$,user")

			objComputersFile.Write objComputer.AdsPath
			objComputersFile.Write "|"
			objComputersFile.Write objDomain.AdsPath
			objComputersFile.Write "|"
			objComputersFile.Write objComputer.Name 
			objComputersFile.Write "|" 
			objComputersFile.Write objComputerAccount.PasswordAge 
			objComputersFile.Write "|" 
			objComputersFile.Write objComputer.Owner
			objComputersFile.Write "|" 
			objComputersFile.Write objComputer.Division
			objComputersFile.Write "|" 
			objComputersFile.Write objComputer.OperatingSystem
			objComputersFile.Write "|" 
			objComputersFile.Write objComputer.OperatingSystemVersion
			objComputersFile.Write "|" 
			objComputersFile.Write objComputer.Processor
			objComputersFile.Write "|" 
			objComputersFile.Write objComputer.ProcessorCount
			objComputersFile.WriteLine

			'COMPUTER USERS
			If blnLocalUsers Then
				Set objUsers = Nothing
				Set objUser = Nothing
				Set objUsers = GetObject(objComputer.AdsPath & ",computer")
				objUsers.Filter = Array("User")

				For Each objUser in objUsers
					objUsersFile.Write objUser.AdsPath
					objUsersFile.Write "|"
					objUsersFile.Write objComputer.AdsPath
					objUsersFile.Write "|"
					objUsersFile.Write objUser.Name
					objUsersFile.Write "|"
					objUsersFile.Write objUser.FullName
					objUsersFile.Write "|"
					objUsersFile.Write objUser.Description
					objUsersFile.Write "|"
					objUsersFile.Write objUser.PasswordAge
					objUsersFile.Write "|"
					objUsersFile.Write objUser.LastLogin
					objUsersFile.Write "|"
					objUsersFile.Write objUser.LastLogoff
					objUsersFile.Write "|"
					objUsersFile.Write objUser.RasPermissions
					objUsersFile.Write "|"
					If objUser.UserFlags And &H0002 Then 
						objUsersFile.Write "1"
					Else 
						objUsersFile.Write "0"
					End If
					objUsersFile.WriteLine
				Next
			End If
			
			'COMPUTER GROUPS
			If blnLocalGroups Then
				Set objGroups = Nothing
				Set objGroup = Nothing
				Set objGroups = GetObject(objComputer.AdsPath & ",computer")
				objGroups.Filter = Array("Group")

				For Each objGroup in objGroups
					objGroupsFile.Write objGroup.AdsPath 
					objGroupsFile.Write "|"
					objGroupsFile.Write objComputer.AdsPath
					objGroupsFile.Write "|"
					objGroupsFile.Write objGroup.Name
					objGroupsFile.WriteLine

					For Each objUser In objGroup.Members
						If Right(objUser.Name, 1) <> "$" Then
							objGroupMembersFile.Write objGroup.AdsPath
							objGroupMembersFile.Write "|"
							objGroupMembersFile.Write objUser.AdsPath
							objGroupMembersFile.WriteLine
						End If
					Next
				Next
			End If

			'SERVICES
			If blnServices Then
				Set objServices = Nothing
				Set objService = Nothing
				Set objServices = GetObject(objComputer.AdsPath & ",computer")
				objServices.Filter = Array("Services")

				For Each objService In objServices
					objServicesFile.Write objService.AdsPath 
					objServicesFile.Write "|"
					objServicesFile.Write objComputer.AdsPath
					objServicesFile.Write "|"
					objServicesFile.Write objService.Name
					objServicesFile.Write "|"
					objServicesFile.Write objService.DisplayName
					objServicesFile.Write "|"
					objServicesFile.Write objService.ServiceAccountName
					objServicesFile.WriteLine
				Next
			End If
		Next
	End If
	
Next

objServicesFile.Close
objComputersFile.Close
objGroupMembersFile.Close
objGroupsFile.Close
objUsersFile.Close
objDomainsFile.Close
Set objServicesFile = Nothing
Set objComputersFile = Nothing
Set objGroupMembersFile = Nothing
Set objGroupsFile = Nothing
Set objUsersFile = Nothing
Set objDomainsFile = Nothing