Showing posts with label inventory. Show all posts
Showing posts with label inventory. Show all posts

Wednesday, December 27, 2006

Licensing: Year-end Software License Compliance

Having recently gone though a software licensing inventory update , I thought that since it's year-end for a lot of people, I'd let you know what we do internally - as well as link-up some tools and suggestions. That said, I'm very interested to hear how readers approach and manage licensing issues so feel free to comment.

First of all, and I think everyone knows this... there are lots of tools to help you manage software licensing. So perhaps the first thing to consider is the size of your environment. If you have a small to midsized network - say even up to a few thousand machines - than there are many low/no-cost options available to you. If you're in a large environment... tens-of-thousands or more users, than you probably should be going with an enterprise-class solution. While we do work for some large clients - and manage some powerful tools for them like BigFix - internally, we're still in the small-to-midsized category. So that's where I'll focus.

For us, everything starts with my my AD-COIT hardware/software inventory script that I created to help me automate some of this effort. Consider grabbing a copy and trying it out yourself. I run it, and it just outputs a report - one that I've customized a bit for myself. But perhaps you want something with the Microsoft stamp of approval... then check out the Microsoft Software Inventory Analyzer (MSIA)... it's purpose-built for software inventory work. The reports are great, and the only real downside is if you support an application stack that has a lot of non-Microsoft applications, in that case you might not see everything you need with MSIA.

Next, I look at the last few lines of of the AD-COIT output to see if any computers failed to respond, or perhaps were out of the office. Since the script runs in real-time, it won't catch systems that are persistently out-of-the-office and for this group, there are a few options... what I do is create a global-group of "out-of-office" users, and scope a GPO to run a login-script that updates .txt files on a hidden share whenever users in this group are in the office. In practical terms this means looking a handful of text files and and doing a bit of manual consolidation to update my license counts.

Finally, I dump everything into a spreadsheet and compare it with our licensing information to produce a report of "Licenses in use", verses "Licenses Owned", which I then use to drive decision making and software budgeting. These inventory checks are done on a scheduled, quarterly basis, and it keeps us up-to-date in terms of compliance.

There are other good tools available as well... Spiceworks 1.0 for instance does a ton of useful stuff, has good reports, and is essentially free. I've tested it a bit, but haven't added it into the mix for licensing checks. Long-term for us, I think BigFix is actually going to make a lot of sense for us to deploy internally. Besides license discovery, it is very powerful agent-based patch-deployment and reporting tool that works in near-real-time.

How do you manage software licensing compliance?

Monday, December 04, 2006

WMI: AD-COIT v2.3 (Computer Object Intentory Tool)

Updated: 1/15/07, For the latest release information go here.

Updated: 1/9/07, Instead of struggling with the extra characters and formatting issues associated with posting long scripts to blogger (see the comments below), I created a project for AD-COIT over on Sourceforge. From there, you can download the entire working script. While I plan to post information and updates to the blog, you’ll be able to find the latest release there. I'll leave the code posted below - so that you can review the logic and skim though it easily. However, if you want a copy of it...

Download the latest version of AD-COIT.


12/4/06, It's been a while since I've posted an update to my AD Workstation Inventory script, so the other day when I was using it to troubleshoot antivirus-definition updates on a few clients, I figured now would be as good of time as any to post my changes (and to do a name-change to "AD-COIT" for "Active Directory Computer Object Inventory Tool").

In any case, refer here for basic usage and instructions - as they've not really changed since my last update. You should be able to just copy and paste the below code snippet into notepad and save it with a .VBS extension. Let me know if you have any trouble doing so.

Otherwise, if you're interested in the logic or how I came up with the functions, you can check out my WMI category. If you're interested in the output, I'll post that in a follow-up.


' AD Computer Object Inventory Tool v2.3, by wmi.wmi@gmail.com
'------------------------------
' Usage: "cscript scriptname.vbs >inventoryreport.txt"

'=== Begin Script Configuration ===
strLdapPath = "'LDAP://DC=domain,DC=local'" 'Set to relflect your LDAP path
'=== End Script Configuration ===

Dim rootDSE
Dim DistinguishedName
Dim objShell,objDef,objDate,objVer,objRev,objOutFile,objFSO,objNDate,objToday, strRole
Const MegabyteConversion = 1048576
Const Warning_Threshold = 1000
Set objShell = CreateObject("WScript.Shell")


wscript.echo strLdapPath
dsqueryFSMOroles

'Set rootDSE = GetObject("LDAP://rootDSE")
'strLdapPath = "'LDAP://" & rootDSE.Get("defaultNamingContext")'"
'wscript.echo strLdapPath

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 " & strLdapPath & " Where objectCategory='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)
strText=""
Do While Not objExecObject.StdOut.AtEndOfStream
strText = objExecObject.StdOut.ReadAll()
If Instr(strText, "Reply") > 0 Then
Set objWMIService = GetObject _
("winmgmts:\\" & strComputer & "\root\cimv2")
If Err.Number > 0 then
strErrorSystems = strComputer & ", " & strErrorSystems
else
BuildHeader
OperatingSystem
BiosQuery
ProcQuery(strComputer)
DayLightSavingsEffect(strComputer)
SavDate(strComputer)
Diskspace
ListInstalledApplications
BuildFooter
end if
Err.Clear 'flushes error code from previous loop
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


Function ListInstalledApplications
Set colItemsProduct = objWMIService.ExecQuery("Select * from Win32_Product")
Wscript.echo "Workstation Application List:"
Wscript.Echo "-----------------------------"
For Each objItemProduct in colItemsProduct
Wscript.echo objItemProduct.Description & " (v." & objItemProduct.Version & ")"
'Wscript.echo "Location: " & objItem.InstallLocation & ", "
Next

End Function

Function dsqueryFSMOroles
Dim objShell, ArrFSMOCmds(4)
Set objShell = CreateObject("WScript.Shell")

Cmd1 = "cmd /c"
Cmd2 = "dsquery server -hasfsmo "
ArrFSMOCmds(0) = "schema"
ArrFSMOCmds(1) = "rid"
ArrFSMOCmds(2) = "name"
ArrFSMOCmds(3) = "infr"
ArrFSMOCmds(4) = "PDC"

For Each ArrFSMOCmds in ArrFSMOCmds
Set objExec = objShell.Exec(Cmd1 & Cmd2 & ArrFSMOCmds)
strExecResults = LCase(objExec.StdOut.ReadAll)
Wscript.Echo ArrFSMOCmds & ": " & strExecResults
Next

End Function


Function BuildHeader
Wscript.Echo "-------------------------------------------------------------"
Wscript.Echo "Computer Name: " & strComputer
Wscript.Echo "-------------------------------------------------------------"
End Function
Function OperatingSystem
Set colItems = objWMIService.ExecQuery ("Select * From Win32_OperatingSystem")
For Each objItem in ColItems
strOs = objItem.Caption
strServPack = objItem.CSDVersion
strInstallDate = objItem.InstallDate
Next
Wscript.Echo "Operating System: " & strOs
Wscript.Echo "Service Pack: " & strServPack
Wscript.Echo "Install Date: " & WMIDateStringToDate(strInstallDate)
End Function
Function BiosQuery
Set colItems2 = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
For Each objItem in colItems2
strDellTag = objItem.SerialNumber
strManu = objItem.Manufacturer
strBiosName = objitem.Name
Next
WScript.Echo "Manufacturer: " & strManu
Wscript.Echo "BIOS Name: " & strBiosName
Wscript.Echo "Service Tag: " & strDellTag
End Function
Function WMIDateStringToDate(dtmDate)
WScript.Echo dtm:
WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) & "/" & _
Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _
& " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2))
End Function
Function ProcQuery(shost)
Set colItems4 = objWMIService.ExecQuery("SELECT * FROM Win32_Processor", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem in colitems4
strProcessor = objItem.Name
Next
Wscript.Echo "Processor type: " & strProcessor
End Function
Function DayLightSavingsEffect(shost)
Set colItems3 = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)

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

Select Case strDomainRole
Case 0
strRole = "Standalone workstation"
Case 1
strRole = "Member workstation"
Case 2
strRole = "Standalone server"
Case 3
strRole = "Member server"
Case 4
strRole = "Backup domain controller"
Case 5
strRole = "PDC Emulator"
End Select
Wscript.Echo "Domain Role: " & strRole
Wscript.Echo "Current User: " & strUsername
Wscript.Echo "Model: " & strModel
Wscript.Echo "RAM: " & strRAM
Wscript.Echo "Daylight Savings in effect: " & strDayLIghtSavings
Wscript.Echo "Time Zone: " & strTimeZone
strUsername = ""
End Function
Function SavDate(shost)
strCmdRun = "cmd /c"
strRegQ = "reg query "
strRegKey = "\HKLM\SOFTWARE\Symantec\SharedDefs\"
strCmdSw = " /v "
strRegKey2 = "DEFWATCH_10"
Set objExec = objShell.Exec(strCmdRun & strRegQ & "\\" & shost & strRegKey & strCmdSw & strRegKey2)
strExecResults = LCase(objExec.StdOut.ReadAll)
objVer = Right(strExecResults,16)
objRev = Right(objVer,7)
objDate = Left(objVer,8)
objYear = Left(objDate,4)
objMonth = Mid(objDate,5,2)
objDay = Right(objDate,2)
objNDate = CDATE(objMonth &"/"& objDay &"/"& objYear)
Wscript.Echo "Symantec Antivirus Definition Date: " & objNDate &" Rev. "& objRev & " "
End Function
Function DiskSpace
Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk")
If colLogicalDisk.Count = 0 Then
Wscript.Echo "No drives exist on this computer."
Else
For Each objLogicalDisk in colLogicalDisk
FreeMegaBytes = objLogicalDisk.Freespace / MegabyteConversion

'If objLogicalDisk.DriveType = 3 Then
If FreeMegaBytes <> 0 Then
FreeMegaBytes_String = Int(FreeMegaBytes) & " MB Free"
Wscript.Echo objLogicalDisk.DeviceID & ", " & FreeMegaBytes_String &amp;amp;amp; ", " & objLogicalDisk.Description
End if
Next
End if
End Function
Function BuildFooter
Wscript.Echo "-------------------------------------------------------------"
End Function


Tuesday, November 07, 2006

Tools: Spiceworks Desktop Goes 1.0

Have you checked out the Spiceworks Desktop yet (backed by Austin Ventures)? It just went 1.0 today and is basically an asset inventory app with a slick web interface and some community integration targeted at the SMB sector. The community part looks new to me, but I skipped the last few beta releases and am only now revisiting.

In case you haven’t heard, the buzz around these guys is the business model... Google Adwords inserted in a web app. Spice and Goldcoins blogged about this a while back. My take...

It's worth checking out.

But if you're looking for a basic command-line inventory tool, that will output to CSV, check out my AD-COIT project on Sourceforge.

Monday, February 27, 2006

WMI: Get a list of installed applications

Have you ever needed to get a list of applications that are installed on a workstation? I can think of a number of situations where this might be useful… Maybe you’re trying to get an application count as part of a Software Asset Management (SAM) project, or maybe because you’ve been tasked with determining the popularity of something inside your organization, say RSS Bandit (keep in mind that this list only includes applications installed by the Windows Installer).

Personally, I’ll be adding this as a function to my inventory script - because right now, I need this list for an audit I'll be conducting at a customer site.

Let’s just quickly review how this works…

First we declare a string (strComputer), and assign a value to it (ComputerName). Next, we connect to the \root\cimv2 namespace, query the “Win32_Product” class, and get a collection of items (colItems). Finally, we loop though the collection and echo the objItem.Descriptions and objItem.Versions.


strComputer = "computerName"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Product")

For Each objItem in colItems
wscript.echo objItem.Description & " (v." & objItem.Version & ")"
Next


Thursday, December 08, 2005

WMI: Changes to Workstation Inventory

Joe pointed out that in the workstation inventory script that I recently posted, it’s considerably more efficient to use objectCategory=’computer’ than objectClass. I made the recommended change, and sure enough, it worked, and worked more quickly. Thanks joe!

If you want to follow along, consider the following change…


"Select Name, Location from " & strLdapPath & " Where objectClass='computer'"

to

"Select Name, Location from " & strLdapPath & " Where objectCategory='computer'"


After I’ve completed some more work on the script, I’ll post the new version in it’s entirety, incorporating this update.

Tuesday, December 06, 2005

WMI: Active Directory Workstation inventory, version 2

I cleaned the original Active Directory workstation inventory script that I mentioned in last week’s post. Basically, I broke the logic out into functions, adding the free disk space check, and the Symantec antivirus definition date check, and made it a bit more readable and usable than the original script.

So how should you go about using this?


Well, first thing you’ll want to do is modify your LDAP path (search for the strLdapPath string) to make this work on your network. I have this commented, and it should be relatively self-explanatory.

The next thing you’ll want to do is consider if you should run the script. If you’ve got a larger environment (say hundreds or thousands of workstations) then it’s going to take quite a while to run. But on a small to mid-sized network, this shouldn’t be too bad.

What do I type to make this work?

So you copy and paste the below code into a text editor, and save it with a .VBS extension. Then, you make sure you’re either logged in as a domain admin, or that you’re executing this script under the context of a domain admin account, you then modify the LDAP path, drop to the command line, and use the following command:

“cscript scriptname.vbs >inventoryreport.txt”

This is going to iterate though all of the computer objects in active directory, ping them to determine if they’re on, and then do some work. Which after hitting all of the objects will leave you with a text file that contains all of your workstation names, their operating system versions, service pack levels, installation dates, computer manufacturer, bios revisions, service tags, processor types, currently logged-on user, model number, amount of ram, daylight savings zone, Symantec antivirus definition dates, and the amount of available free disk space.

Why is it just sitting here doing nothing?

It’s probably doing work. If you’d rather see the results echoed to the screen, then just get rid of the redirection, using the following command line “cscript scriptname.vbs”.

How is this useful?

Well, if you’re an administrator on a small to midsized network, this is a really handy inventory tool that can be used quickly and with very limited editing on your internal and/or customer networks. As a result, it’s cost effective, and you can audit or spot-check your clients. Secondly, if you take a look at a recent post of Susan Bradley, you’ll see this automates a bit of what new SBS net-admins need to for health-check and monitoring type of functions.

I plan to follow-up this post with some more specifics as to how I’m using on the SMB side of the business, and also start thinking about ways I can improve this (think Exchange database sizes) or to make it scale well for larger environments.


'AD Workstation Inventory version 2
'by Nick, wmi.wmi@gmail.com, http://addicted-to-it.blogspot.com
Dim objShell,objDef,objDate,objVer,objRev,objOutFile,objFSO,objNDate,objToday
Const MegabyteConversion = 1048576
Const Warning_Threshold = 1000

'=================================================
'Set the LDAP path to your Active Directory
'=================================================
strLdapPath = "'LDAP://DC=domain,DC=local'"
wscript.echo strLdapPath
'=================================================

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 " & strLdapPath & " 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")

'=================================================
'The following functions produce the reports
'=================================================

If Err.Number > 0 then
strErrorSystems = strComputer & ", " & strErrorSystems
else
BuildHeader
OperatingSystem
BiosQuery
ProcQuery(strComputer)
DayLightSavingsEffect(strComputer)
SavDate(strComputer)
Diskspace
BuildFooter

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

Function BuildHeader
Wscript.Echo "-------------------------------------------------------------"
Wscript.Echo "Computer Name: " & strComputer
Wscript.Echo "-------------------------------------------------------------"
End Function

Function OperatingSystem
Set colItems = objWMIService.ExecQuery ("Select * From Win32_OperatingSystem")
For Each objItem in ColItems
strOs = objItem.Caption
strServPack = objItem.CSDVersion
strInstallDate = objItem.InstallDate
Next
Wscript.Echo "Operating System: " & strOs
Wscript.Echo "Service Pack: " & strServPack
Wscript.Echo "Install Date: " & WMIDateStringToDate(strInstallDate)

End Function



Function BiosQuery
Set colItems2 = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
For Each objItem in colItems2
strDellTag = objItem.SerialNumber
strManu = objItem.Manufacturer
strBiosName = objitem.Name
Next
WScript.Echo "Manufacturer: " & strManu
Wscript.Echo "BIOS Name: " & strBiosName
Wscript.Echo "Dell Service Tag: " & strDellTag
End Function

Function WMIDateStringToDate(dtmDate)
WScript.Echo dtm:
WMIDateStringToDate = CDate(Mid(dtmDate, 5, 2) &amp;amp;amp;amp;amp; "/" & _
Mid(dtmDate, 7, 2) & "/" & Left(dtmDate, 4) _
& " " & Mid (dtmDate, 9, 2) & ":" & Mid(dtmDate, 11, 2) & ":" & Mid(dtmDate,13, 2))
End Function


Function ProcQuery(shost)
Set colItems4 = objWMIService.ExecQuery("SELECT * FROM Win32_Processor", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem in colitems4
strProcessor = objItem.Name
Next
Wscript.Echo "Processor type: " & strProcessor

End Function



Function DayLightSavingsEffect(shost)
Set colItems3 = objWMIService.ExecQuery("Select * from Win32_ComputerSystem",,48)
For Each objItem in colitems3
strUserName = objItem.Username
strModel = objItem.Model
strRAM = objItem.TotalPhysicalMemory
strTimeZone = (objItem.CurrentTimeZone / 60)
strDayLightSavings = objItem.DaylightInEffect
Next

Wscript.Echo "Current User: " & strUsername
Wscript.Echo "Model: " & strModel
Wscript.Echo "RAM: " & strRAM
Wscript.Echo "Daylight Savings in effect: " & strDayLIghtSavings
Wscript.Echo "Time Zone: " & strTimeZone
strUsername = ""
End Function



Function SavDate(shost)
strCmdRun = "cmd /c"
strRegQ = "reg query "
strRegKey = "\HKLM\SOFTWARE\Symantec\SharedDefs\"
strCmdSw = " /v "
strRegKey2 = "DEFWATCH_10"
Set objExec = objShell.Exec(strCmdRun & strRegQ & "\\" & shost & strRegKey & strCmdSw & strRegKey2)
strExecResults = LCase(objExec.StdOut.ReadAll)

objVer = Right(strExecResults,16)
objRev = Right(objVer,7)
objDate = Left(objVer,8)
objYear = Left(objDate,4)
objMonth = Mid(objDate,5,2)
objDay = Right(objDate,2)
objNDate = CDATE(objMonth &amp;amp;amp;amp;amp;"/"& objDay &"/"& objYear)
Wscript.Echo "Symantec Antivirus Definition Date: " &amp;amp;amp;amp;amp; objNDate &" Rev. "& objRev & " "

End Function



Function DiskSpace
Set colLogicalDisk = objWMIService.InstancesOf("Win32_LogicalDisk")
If colLogicalDisk.Count = 0 Then
Wscript.Echo "No drives exist on this computer."
Else
For Each objLogicalDisk in colLogicalDisk
FreeMegaBytes = objLogicalDisk.Freespace / MegabyteConversion

'If objLogicalDisk.DriveType = 3 Then
'If FreeMegaBytes <> 0 Then
FreeMegaBytes_String = Int(FreeMegaBytes) & " MB Free"
Wscript.Echo objLogicalDisk.DeviceID & ", " & FreeMegaBytes_String & ", " &

objLogicalDisk.Description
End if

'End If
'End If
Next
End if
End Function

Function BuildFooter
Wscript.Echo "-------------------------------------------------------------"
End Function

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

Tuesday, August 23, 2005

WMI: Using WMI to Find Dell Express Service Tags

Need an easy way to determine the express service tag of a Dell machine, or a series of machines? Just copy and past the following code into a *.vbs file, and run it using the following command line: “scriptname.vbs Workstation1 Workstation2…”.

On Error Resume Next
If Wscript.Arguments.Count = 0 Then
Wscript.Echo "Usage: scriptname.vbs workstation1 [ws2] [ws3] ..."
Wscript.Quit
End If

For Each strComputer In Wscript.Arguments
Set objWMIService = GetObject("winmgmts://" & Computer)

If Err.number <> 0 then
Wscript.Echo Computer & ", " & Err.Description
'Err.clear Resets the error code
Err.Clear
else

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_BIOS",,48)
End If

For Each objItem In colItems
Wscript.Echo strComputer &amp; ": " & objItem.SerialNumber
Next
Next