Wednesday, September 07, 2005

WMI: Step 2, Gathering a computer inventory of available systems from Active Directory

As I started to add features to my previous script, I realized that it got a little buggy when more than a couple of machines were going to be queried. And it was pretty obvious that it lacked any error handling. So with these things in mind, I decided to start over.

Being able to find service tags is convenient and all, but what I really wanted to do was get a quick inventory of the workstations connected to my LAN, gathering a wish-list of such items as: machine names with logged-on users, manufacturer names, model numbers, service tags, processor speeds, ram quantities, time zone settings, and daylight savings information.

Most importantly, I wanted this to be reasonably portable. I didn’t want to have to jump though hoops to get this to work at a different customer site… no creating a text file with all of the machine names in it, or having to export computer names to a CSV file … basically I wanted to minimize the amount of prep work needed, so that someone could “hit-the-ground-running” with the least amount of effort. Oh, and let’s not forget adding a little error handling…

I had an existing script that did some work against objects in an OU, so I could have probably used that as a starting point. But in order to really meet the error handling requirements, I decided to use a ping test against computer objects in active directory to determine if a machine was powered-up or not. The Microsoft Script Center has a scriptomatic) that I’ll need to meet my objectives. Then I added my for-next loops which actually load the items that I’m interested in, into string variables (e.g. strOS, strManu, etc), doing work where appropriate to make the output readable. Finally, I use wscript.echo commands to echo the reported data to the screen. Also, at the beginning of my main do-loop you’ll notice the If-Then statement that basically says…"If I get a ping response do this, else do this”… it’s that other else that does my error handling. So if a machine isn’t on, I add each machine to a string that will get echo’d at the end.

Check it out. And if you have any questions, comments, etc... post them in the comment section!

On error resume next
Const ADS_SCOPE_SUBTREE = 2
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCOmmand.ActiveConnection = objConnection
objCommand.CommandText = _
"Select Name, Location from 'LDAP://DC=domainname,DC=local' " _
& "Where objectClass='computer'"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Do Until objRecordSet.EOF
strComputer = objRecordSet.Fields("Name").Value

Set objShell = CreateObject("WScript.Shell")
strCommand = "%comspec% /c ping -n 3 -w 1000 " & strComputer & ""
Set objExecObject = objShell.Exec(strCommand)

'clears echo replies left in strText from the previous loop
strText=""
Do While Not objExecObject.StdOut.AtEndOfStream
strText = objExecObject.StdOut.ReadAll()
If Instr(strText, "Reply") > 0 Then
Set objWMIService = GetObject _
("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * From Win32_OperatingSystem")
Set colItems2 = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
' Wscript.Echo Err.Description
Set colItems3 = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)
Set colItems4 = objWMIService.ExecQuery("SELECT * FROM Win32_Processor", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem in ColItems
strOS = objItem.Caption
Next

For Each objItem in colItems2
strDellTag = objItem.SerialNumber
strManu = objItem.Manufacturer
Next

For Each objItem in colitems3
strUserName = objItem.Username
strModel = objItem.Model
strRAM = objItem.TotalPhysicalMemory
strTimeZone = (objItem.CurrentTimeZone / 60)
strDayLightSavings = objItem.DaylightInEffect
Next

For Each objItem in colitems4
strProcessor = objItem.Name
Next
If Err.Number > 0 then
strErrorSystems = strComputer & ", " & strErrorSystems
else
Wscript.Echo "Computer Name: " & strComputer
Wscript.Echo "Operating System: " & strOS
Wscript.Echo "Current User: " & strUserName
WScript.Echo "Manufacturer: " & strManu
Wscript.Echo "Model: " & strModel
Wscript.Echo "Dell Service Tag: " & strDellTag
Wscript.Echo "Processor type: " & strProcessor
Wscript.Echo "RAM: " & strRAM
Wscript.Echo "Time Zone: " & strTimeZone
Wscript.Echo "Daylight Savings in effect: " & strDayLIghtSavings
Wscript.Echo " "
end if
'flushes error code from the previous loop
Err.Clear
Else
UnavailableSystems = strComputer & ", " & UnavailableSystems
End If
Loop
objRecordSet.MoveNext
Loop
Wscript.Echo "The following systems were unavailable: " & UnavailableSystems
Wscript.Echo " "
Wscript.Echo "The following systems were on, but returned an error: " & strErrorSystems

No comments: