DomainReportManager.vbs
Two months ago we introduced the DomainReportManager script package, a tool
for assaying all your installed Windows hardware, software in the network. This
month, we’ll take a dive into the orchestrator of the suite,
DomainReportManager.vbs.
DomainReportManager provides your sole interface to the operation of choosing
what systems to survey, manage how many systems are being inventoried at any
given time and, finally, launching the HardwareReportCompiler, the tool which
parses out all the system inventories into usable, organized information about
your collection of systems.
Rather than running through the entire script, we’ll examine a few of the
more essential areas controlling DomainReportManager’s behavior.
Enumerating the Namespace
The Active Directory Services Interface provides the mechanism by which we
identify all the available NT compatible computer organizations. Getting started
with ADSI is simple but the documentation available at Microsoft is fairly,well,
rotten. It's obvious that the editor's expected audience is the C++ crowd. We
mustn't let that get in our way though! Spend some time working with the
examples you'll find at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/active_directory_service_interfaces_adsi.asp?frame=true.
For our purposes, we need to connect to the WinNT namespace and enumerate all
the available workgroups and domains.
'====================================================================
Set NameSpace = GetObject("WinNT:")
ReDim arrNameSpace(0)
For Each DomainObj In NameSpace
Boundary=UBound(arrNameSpace)
If arrNameSpace(Boundary) = "" Then
arrNameSpace(Boundary) = DomainObj.Name
Else
ReDim Preserve arrNameSpace(Boundary + 1)
arrNameSpace(Boundary + 1) = DomainObj.Name
End If
Next
'====================================================================
Once arrNameSpace is populated, we present the list to you and allow you to
choose from amongst the listed domains which are presented 3 to each line.
'====================================================================
Boundary=UBound(arrNameSpace)
If Boundary >= 2 Then
For NameCount = 0 to UBound(arrNameSpace) Step 3
strResult = strResult & arrNameSpace(NameCount) & ", " & _
arrNameSpace(NameCount + 1) & ", " & _
arrNameSpace(NameCount + 2) & vbNewLine
Next
ElseIf Boundary = 1 Then
strResult = arrNameSpace(0) & vbTab & _
arrNameSpace(1)
ElseIf Boundary = 0 Then
strResult = arrNameSpace(0)
End If
On Error GoTo 0
strResult = "These are the detected Domain/Workgroup NameSpaces." & _
vbNewLine & "Please choose one or type the name of another NameSpace " & _
vbNewLine & "you'd like to survey:" & vbNewLine & vbNewLine & _
strResult & vbNewLine & vbNewLine & ">"
wscript.echo strResult
Input = ""
Do While Not WScript.StdIn.AtEndOfLine
Input = Input & WScript.StdIn.Read(1)
Loop
'====================================================================
Pretty simple so far, eh? Good!
Using similar techniques with the ADSI objects, your choice of domains is
queried for the names of all member computer accounts in that organization. And
this is where we enter another realm of uncertainty when we use script.
Controlling the Number of Systems Being Inventoried
Accessing the Win32 API with Windows Script Host is not supported. Script
authors often write 'wrapper' classes which they compile into DLLs and register,
or install, those DLLs on the systems from which they'll run their code. That
solution has always bugged me as getting in the way of what we write scripts
for. I don't want to register another DLL on every system I might need to touch.
I ought to be able to copy my code files to the target system and not have to
alter that system at all. I also don't want to reboot that system.
Unfortunately, those restrictions mean that I can't use the Win32 API to
enumerate how many instances of a script are running, a little more creativity
is required.
Whenever you want to get intimate with a Windows system in script, don't sell
Windows Management Instrumentation (WMI) short. A short examination of the Win32
SDK reveals that there is a WMI provider available which will let us measure how
many systems we're querying at any time. All we have to do is count them and
keep firing up inventories until we hit our limit...and when we do, we'll wait
for a while until we have some headroom. This technique will also allow us to
tell when it's time to fire up the HardwareReportCompiler. How convenient!
'====================================================================
Function HowMany()
Dim Proc,Procs
Set Procs = GetObject("winmgmts:{ImpersonationLevel = Impersonate}\\."). _
InstancesOf("Win32_Process")
HowMany=0
For Each Proc in Procs
If LCase(Proc.Caption) = "cscript.exe" Then
HowMany=HowMany + 1
End If
Next
End Function
'====================================================================
And that's it in a nutshell! DomainReportManager also does a number of other
more pedestrian jobs like setting up the output folders into which the system
inventories are saved and it does the majority of the logging that goes on
during a domain survey.
In the next installment, we'll examine the script that harvests all the
system information on the network, Inventory.vbs. This script catches much more
information than we'll be examining with the HardwareReportManager and can
easily be customized to add even more detail if you want.
|