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