Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Inventorying Software 1

Status
Not open for further replies.
Oct 10, 2003
90
US
The script below works for the most part, but I am having a problem with the problem PCs and would like a comment or two.

My test file has 3 PCs listed. The 1st and 3rd are turned on and are accessible. The 2nd is turned off. Theoretically, I will see inventories of 2 PCs on the output file and the single bad PC in the failed.txt file. In actuality, it inventories the 1st, lists the 2nd and ends the script w/o looking at #3. Take the problem PC out and it inventories both 1 & 3. My question now is why???


softinv7.vbs

On Error Resume Next

computer = InputBox("Enter COMPLETE path to the source file","Input source","c:\scripts\lists\")
badPC = inputbox ("Enter the name of problem PCs"," ","c:\scripts\output\failed.txt")

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set invOut = objFSO.CreateTextFile("c:\scripts\output\software.tsv", True)
set failedmachines=objFSO.createtextfile(badPC)

Const HKEY_LOCAL_MACHINE = &H80000002
Const ForReading = 1

invOut.WriteLine "IP Address" & vbTab & "Caption" & vbtab & _
"Identifying Number" & vbtab & _
"Install Date" & vbtab & "Install Location" & vbtab & _
"Name" & vbtab & _
"Package Cache" & vbtab & "Vendor" & vbtab _
& "Version"

Set objTextFile = objFSO.OpenTextFile _
(computer, ForReading)

Do Until objTextFile.AtEndOfStream

StrComputer = objTextFile.Readline

call invsoft

Loop

invOut.Close

MsgBox "Software is now inventoried"

'=================================================================
Sub invsoft

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

If Err Then

HandleErr()
Err.Clear

Else

Set colSoftware = objWMIService.ExecQuery _
("Select * from Win32_Product")

For Each objSoftware in colSoftware
invOut.WriteLine strComputer & vbtab & _
objSoftware.Caption & vbtab & _
objSoftware.IdentifyingNumber & vbtab & _
objSoftware.InstallDate & vbtab & _
objSoftware.InstallLocation & vbtab & _
objSoftware.Name & vbtab & _
objSoftware.PackageCache & vbtab & _
objSoftware.Vendor & vbtab & _
objSoftware.Version
Next

End If

End Sub
'=================================================================

'=================================================================
Sub HandleErr()
failedmachines.WriteLine strComputer & " " & "Had error # " & Err.Number
End Sub
'=========================================================
 
Have you tried to replace this :
If Err Then
By this ?
If Err.Number Then

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Didn't seem to help, symptoms are the same.

Is it the flow of the script is not right? It tracks logically to me. Not sure if I am leaning towards the If then being the problem or the do loop.

Any more suggestions?
 
Perhaps an On Error Resume Next instruction in the Sub

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
Hello desktoprat,

[1] As you rightly intended to capture the error on the binding to a failed m/c, so as PHV pointed out, it is there within the scope of the sub you need the "on error resume next" the most.

Also some minor trouble spots.
[2] On the statement creating the badPC file, if you run the script twice, you might run into non-captured runtime error let-go only by the on error resume next. You need to change it with overwrite being true
set failedmachines=objFSO.createtextfile(badPC, true)
[3] Need to close badPC as well.
badPC.close
invOUT.close 'as done already
[4] In principle, when you createtextfile for invOUT and badPC, they are already textstream object ready for being written. Hence, there is no need to later .opentextfile referring to them. Or if keeping the later makes thing clearer (in the writing aspect), then I would myself prefer adding
badPC.close
invOUT.close
immediately after the .createtextfile().

regards - tsuji
 
Just not seeing it. The following script appears to work against a sample of 10 computers, some off, some on, wrong passwords, etc. But I am not sure why this iteration works. Any comments?

softinv9.vbs

Set objFSO = CreateObject("Scripting.FileSystemObject")

'Set the output file for the inventory
Set objTextFile = objFSO.CreateTextFile("c:\scripts\output\software.tsv", True)

'Set the columns and the headers of the inventory file
objTextFile.WriteLine "IP Address" & vbtab & _
"Description" & vbtab & "Identifying Number" & vbtab & _
"Install Date" & vbtab & "Package Cache" & vbtab & "Version"

'Set the information for the failed PCs
badPC = inputbox ("Enter the name of file for failed inventory"," ","c:\scripts\output\failed.txt")
set failedmachines=objFSO.createtextfile(badPC, True)

'Select your source list and open the text file
computer = inputbox ("Enter the path of the machines you would like to inventory","","c:\scripts\lists\computers.txt")
set machines=objFSo_Opentextfile(computer)

On Error Resume Next

'Start looping through the machine names in the file

Do While not machines.AtEndOfLine
strComputer = machines.ReadLine

'Connect to the current machine
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colSoftware = objWMIService.ExecQuery _
("Select * from Win32_Product")

'IF you have an error, write to the failed file and do not attempt to inventory

If Err Then

HandleErr()
Err.Clear

Else

'call a subroutine here

call invsoft
objTextFile.WriteLine

End If

loop

'Close everything out
objfailedmachines.Close
objTextFile.Close

MsgBox "Software is now inventoried"

'=================================================================
Sub HandleErr()
failedmachines.WriteLine strComputer & " " & "Had error # " & Err.Number
End Sub
'=================================================================

'=================================================================
Sub invsoft

For Each objSoftware in colSoftware
objTextFile.WriteLine strComputer & vbtab & _
objSoftware.Description & vbtab & _
objSoftware.IdentifyingNumber & vbtab & _
objSoftware.InstallDate & vbtab & _
objSoftware.PackageCache & vbtab & _
objSoftware.Version
Next

End Sub
'=================================================================
 
desktoprat,

>Do While not machines.AtEndOfLine
Do While not machines.AtEndOfStream

- tsuji
 
Tsuji,

I will have to put that in on my next trip by the workplace. I didn't bring the script home with me. But I am trying to figure out why the script is working now versus the 1st iteration. Before I left work earlier this evening, I was able to inventory some 200 machines and log 30 problem PCs to a seperate file.

I messed up the line you pointed out, I moved the On Error Resume Next lower down the line. I left out the 2 constants. Other than that, I put in a lot more comment lines and tried to group things together better. Was the 1st script just composed wrong? Nearly all the same lines in the 1st are in the 2nd.
 
desktoprat,

The 1st script failed mainly because on error resume next has a scope in itself. If you have it in the main program, it doesn't mean its scope covers any sub or function. You have to do it for each sub or function you want that functionality. When a down pc is encountered, an error is thrown and the "if err then" will not even be executed. The control is passed back to the calling stack. But, at the calling stack, there is [1] no error handling, [2] have an "on error resume next" statement. Hence, the program failed silently at that point already.

Let me say draw the point very crudely.
Code:
on error resume next    '<<<[1]
goo= foo()
if err then goo=600
wscript.echo goo

function foo()
	on error resume next    '<<<[2]
	err.raise 6
	if err then foo=100 : exit function
	foo=500
end function
Examine the behavior with :
{a} comment out [1] and [2]
(b) comment out [1]
(c) comment out [2]
(d) comment out none

- tsuji
 
Further notes:

In fact, what I wanted to show mainly as well is the structure with "if err then goo=600" commented out---simulate more close your 1st script. This is the combination what I said failed silently.

- tsuji
 
As always, thanks Tsuji, I think I understand the point you were trying to make.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top