Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 384
  • Last Modified:

Script that can find if a software is installed in each machine in the file.Need to be capable to work through a login script.

Hi,

Script that can find if a software is installed in each machine in the file.Need to be capable to work through a login script.
Need the below script to work with a login script as the script is a little slow.

Can i get all in 1 file need to compare 3 files

Regards
Sharath

strComputers = "computers.txt"
strOutputFile = "SoftwareSearch.csv"
arrSoftware = Array( _
	".NET Framework", _
	"McAfee", _
	"Lotus Notes" _
	)
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const intForReading = 1
Set objFile = objFSO.OpenTextFile(strComputers, intForReading, False)
While Not objFile.AtEndOfStream
	strComputer = objFile.ReadLine
	strResults = """Computer"""
	For Each strProduct In arrSoftware
		strResults = strResults & ",""" & strProduct & """"
	Next
	strResults = strResults & VbCrLf & """" & strComputer & """"
	If Ping(strComputer) = True Then
		On Error Resume Next
		Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
		Set colItems = objWMIService.ExecQuery("Select Name, Version from Win32_Product")
		If Err.Number = 0 Then
			strCurrentPC = strComputer
			For Each strProduct In arrSoftware
				boolFound = False
				For Each objItem In colItems
					If InStr(LCase(objItem.Name), LCase(arrSoftware)) > 0 Then
						boolFound = True
						Exit For
					End If
				Next
				If boolFound = True Then
					strResults = strResults & ",""Yes"""
				Else
					strResults = strResults & ",""No"""
				End If
			Next
		Else
			strResults = strResults & ",""WMI Connection Error"""
		End If
	Else
		strResults = strResults & ",""Unable to ping"""
	End If
	Set objOutput = objFSO.CreateTextFile(strComputer & "_Products.csv", True)
	objOutput.Write strResults
	objOutput.Close
	Set objOutput = Nothing
Wend
objFile.Close
 
MsgBox "Done. Please see the output files for each computer."
 
Function Ping(strComputer)
	Dim objShell, boolCode
	Set objShell = CreateObject("WScript.Shell")
	boolCode = objShell.Run("Ping -n 1 -w 300 " & strComputer, 0, True)
	If boolCode = 0 Then
		Ping = True
	Else
		Ping = False
	End If
End Function

Open in new window

0
bsharath
Asked:
bsharath
  • 22
  • 9
  • 3
1 Solution
 
Krys_KCommented:
Hi Sharath

I have ammended this for you to run in a logon script.
All you need to change is the location of the output file between the borders (hope it makes sense.

I tested this and it works as expected.
You can run it on your machine first to see if it works and then incorporate it into a logon script

Regards
Krystian
Option Explicit
 
 
	Call FindSoftware
 
Sub FindSoftware()
' Version 1.0
' Dated 16-Feb-2009
 
' Optimized for Logon Script
 
' Checks the local machine if software
' is installed  from a list we provide
 
 
 
' Catch Errors Ourselves
	On Error Resume Next
 
' Declare Variables
	Dim fso, wshShell, wshEnv, objWMIService, oFile
	Dim strComputer, strResults, strProduct, sFileLocation
	Dim strHeader
	Dim colItems, objItem
	Dim arrSoftware
	Dim boolFound
	
	Const ForWriting = 2
	Const ForAppending = 8 
	
' ******************************************************************************************
' CHANGE THIS TO YOUR OWN CENTRAL LOCATION - ALL RESULTS WILL GO TO THIS ONE FILE
	
	sFileLocation = "\\ServerName\c$\Temp\Software_Output.csv"
 
' ******************************************************************************************
	
 
' Create Objects
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set wshShell = CreateObject("WScript.Shell")
	Set wshEnv = WshShell.Environment("PROCESS")
 
' Get current machine	
		strComputer = wshEnv("COMPUTERNAME")
 
' Create an array of software we want to look for
		arrSoftware = Array( _
			".NET Framework", _
			"McAfee", _
			"Lotus Notes" _
			)
 
 ' Create a header for the output file
	strHeader = "ComputerName"
		For Each strProduct In arrSoftware
			strHeader = strHeader & "," & strProduct
		Next
 	strHeader = strHeader & vbNewLine
 
 
' Start the output results
		strResults = strResults & strComputer
			
	Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
	Set colItems = objWMIService.ExecQuery("Select Name, Version from Win32_Product")
			
		If Err.Number = 0 Then
 
			For Each strProduct In arrSoftware
				boolFound = False
 
				For Each objItem In colItems
					If InStr(LCase(objItem.Name), LCase(strProduct)) > 0 Then
						boolFound = True
						Exit For
					End If
				Next
 
					If boolFound = True Then
						strResults = strResults & ",Yes"
					Else
						strResults = strResults & ",No"
					End If
			Next
		Else
			strResults = strResults & ",WMI Connection Error"
			Err.Clear
		End If
 
' Put a new line at the  end of our results
	strResults = strResults & vbNewLine
 
 
' ** WRITE RESULTS **
 
' If file exists then append the results, else we create the file and write the header and results
	If fso.FileExists(sFileLocation) = True Then 
		Set oFile = fso.OpenTextFile(sFileLocation, ForAppending, True)
 
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strResults)
	Else
		Set oFile = fso.OpenTextFile(sFileLocation, ForWriting, True)
		
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strHeader & strResults)
	End If 
 
 
' Close the file
	oFile.Close
 
' Release the object from memory
	Set oFile = Nothing
	Err.Clear
 
 
 
End Sub

Open in new window

0
 
bsharathAuthor Commented:
Will there be issues appending a lot of machines data into 1 csv file
0
 
bsharathAuthor Commented:
Will there be issues appending a lot of machines data into 1 csv file
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Krys_KCommented:
Funny you say that, it was my thought after i just posted it.

Here is a slight revision then!
What i've done is moved the FileLocation down and we now pick up the computername in the fileName. That will solve it.

So it would be
Computer_filename.csv


Regards
Krystian

Option Explicit
 
 
	Call FindSoftware
 
Sub FindSoftware()
' Version 1.0
' Dated 16-Feb-2009
 
' Optimized for Logon Script
 
' Checks the local machine if software
' is installed  from a list we provide
 
 
 
' Catch Errors Ourselves
	On Error Resume Next
 
' Declare Variables
	Dim fso, wshShell, wshEnv, objWMIService, oFile
	Dim strComputer, strResults, strProduct, sFileLocation
	Dim strHeader
	Dim colItems, objItem
	Dim arrSoftware
	Dim boolFound
	
	Const ForWriting = 2
	Const ForAppending = 8 
	
' Create Objects
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set wshShell = CreateObject("WScript.Shell")
	Set wshEnv = WshShell.Environment("PROCESS")
 
' Get current machine	
		strComputer = wshEnv("COMPUTERNAME")
 
 
' ******************************************************************************************
' CHANGE THIS TO YOUR OWN CENTRAL LOCATION - ALL RESULTS WILL GO TO THIS ONE FILE
	
	sFileLocation = "\\ServerName\c$\Temp\" & strComputer & "_Software_Output.csv"
 
' ******************************************************************************************
 
 
' Create an array of software we want to look for
		arrSoftware = Array( _
			".NET Framework", _
			"McAfee", _
			"Lotus Notes" _
			)
 
 ' Create a header for the output file
	strHeader = "ComputerName"
		For Each strProduct In arrSoftware
			strHeader = strHeader & "," & strProduct
		Next
 	strHeader = strHeader & vbNewLine
 
 
' Start the output results
		strResults = strResults & strComputer
			
	Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
	Set colItems = objWMIService.ExecQuery("Select Name, Version from Win32_Product")
			
		If Err.Number = 0 Then
 
			For Each strProduct In arrSoftware
				boolFound = False
 
				For Each objItem In colItems
					If InStr(LCase(objItem.Name), LCase(strProduct)) > 0 Then
						boolFound = True
						Exit For
					End If
				Next
 
					If boolFound = True Then
						strResults = strResults & ",Yes"
					Else
						strResults = strResults & ",No"
					End If
			Next
		Else
			strResults = strResults & ",WMI Connection Error"
			Err.Clear
		End If
 
' Put a new line at the  end of our results
	strResults = strResults & vbNewLine
 
 
' ** WRITE RESULTS **
 
' If file exists then append the results, else we create the file and write the header and results
	If fso.FileExists(sFileLocation) = True Then 
		Set oFile = fso.OpenTextFile(sFileLocation, ForAppending, True)
 
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strResults)
	Else
		Set oFile = fso.OpenTextFile(sFileLocation, ForWriting, True)
		
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strHeader & strResults)
	End If 
 
 
' Close the file
	oFile.Close
 
' Release the object from memory
	Set oFile = Nothing
	Err.Clear
 
 
 
End Sub

Open in new window

0
 
bsharathAuthor Commented:
Do you think one file would be an issue.
As multiple files would be difficult to analyze
0
 
bsharathAuthor Commented:
Do you think one file would be an issue.
As multiple files would be difficult to analyze
0
 
RobSampsonCommented:
Hi, writing to one file from many PCs might be an issue with file locks, so you might be best just letting the PCs write to their own files, then whenever you want to look at them, you can use this code to combine them....

Regards,

Rob.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const intForReading = 1
strFolder = "\\server\softwarelogs"
strResults = ""
For Each objFile In objFSO.GetFolder(strFolder).Files
	If Right(LCase(objFile.Name), 4) = ".csv" Then
		Set objCSV = objFSO.OpenTextFile(objFile.Path, intForReading, False)
		If strResults = "" Then
			strResults = objCSV.ReadLine
		Else
			objCSV.SkipLine
			If objCSV.AtEndOfStream Then strResults = strResults & VbCrLf & objCSV.ReadLine
		End If
		objCSV.Close
	End If
Next
Set objOutput = objFSO.CreateTextFile("CombinedCSVs.csv", True)
objOutput.Write strResults
objOutput.Close
Set objOutput = Nothing
MsgBox "Done. See CombinedCSVs.csv"

Open in new window

0
 
bsharathAuthor Commented:
Thanks Rob...

I have placed this script as a startup script but did not run. When run manually it works but not through GPO.

Is there something i am missing
0
 
bsharathAuthor Commented:
Thanks Rob...

I have placed this script as a startup script but did not run. When run manually it works but not through GPO.

Is there something i am missing
0
 
bsharathAuthor Commented:
Hi Rob i just ran the code for combining on the script that you gave me before . Running on a list of computers whose data get dumped into individual files. But just get the one line header
0
 
bsharathAuthor Commented:
Hi Rob i just ran the code for combining on the script that you gave me before . Running on a list of computers whose data get dumped into individual files. But just get the one line header
0
 
RobSampsonCommented:
Oh, messed up line 12 above....this code will combine them.

Regards,

Rob.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const intForReading = 1
strFolder = "\\server\softwarelogs"
strResults = ""
For Each objFile In objFSO.GetFolder(strFolder).Files
	If Right(LCase(objFile.Name), 4) = ".csv" Then
		Set objCSV = objFSO.OpenTextFile(objFile.Path, intForReading, False)
		If strResults = "" Then
			strResults = objCSV.ReadLine
		Else
			objCSV.SkipLine
			If objCSV.AtEndOfStream = False Then strResults = strResults & VbCrLf & objCSV.ReadLine
		End If
		objCSV.Close
	End If
Next
Set objOutput = objFSO.CreateTextFile("CombinedCSVs.csv", True)
objOutput.Write strResults
objOutput.Close
Set objOutput = Nothing
MsgBox "Done. See CombinedCSVs.csv"

Open in new window

0
 
bsharathAuthor Commented:
Thanks Rob worked perfect any ideas on the GPO
0
 
bsharathAuthor Commented:
Thanks Rob worked perfect any ideas on the GPO
0
 
RobSampsonCommented:
As a StartUp script, it will run as the Local System account, so you'll need to change this line:
      sFileLocation = "\\ServerName\c$\Temp\" & strComputer & "_Software_Output.csv"

to point to the NetLogon share on a domain controller.

Create a folder called "Software_Check" or something similar, and change that line to
      sFileLocation = "\\domain.com\NetLogon\Software_Check\" & strComputer & "_Software_Output.csv"

and I think it should work fine.

Regards,

Rob.
0
 
bsharathAuthor Commented:
Still no luck Rob...I restarted the machine few times
Ran a GPUPDATE /force
Still does not create the csv
When i type
Rsop.msc it shows that the script is effective but does not create the csv
0
 
bsharathAuthor Commented:
Still no luck Rob...I restarted the machine few times
Ran a GPUPDATE /force
Still does not create the csv
When i type
Rsop.msc it shows that the script is effective but does not create the csv
0
 
bsharathAuthor Commented:
Rob i just came accross an issue. The script does not fect the correct data
I have 3 of these software components . For all machines i get YES. After 2 days just realized that its wrong. There are many machines that does not have 1 or more softwares
Sophos Anti-Virus      Sophos AutoUpdate      Sophos Remote Management System

Can u please have a look on the main code....
0
 
Krys_KCommented:
Hi Sharath

Are you aware that the code i wrote is looking for
NET Framework"
"McAfee"
"Lotus Notes"

Which i took from your original code you posted.
is this not what you want?

Regards
Krystian

PS
The code you roginally posted had errors in it which might explain why it was taking so long to run.
I can make it run as a script you initiate on your desktop to go to all machines from a file and collect the data into 1 file, thus removing a 2nd script to sort out the individual scripts.

Let me know
0
 
bsharathAuthor Commented:
krystian
yes at this point as the GPO is not working. i would be happy if you could change the script

Yes i did change the 3 softwares to match mine but it did not find the actuals. For all i get "YES"
0
 
bsharathAuthor Commented:
krystian
yes at this point as the GPO is not working. i would be happy if you could change the script

Yes i did change the 3 softwares to match mine but it did not find the actuals. For all i get "YES"
0
 
Krys_KCommented:
ok

will change it for you and then we can look at the problem of all getting yes.

Back shortly

Krystian
0
 
Krys_KCommented:
Hi Sharath

Here is an amended script to run on your own machine.
Its best to run it from the command line

CScript script.vbs

As it will output each computer we are working on as we go round. This will keep you updated to what is going on too.

Change the bit between the borders as before.

There are 2 Ping functions i have added.
Reachable
Ping

At the moment we are using the Reachable one, but if its too slow, try the Ping one. This is only to skip offline machines and will speed the process up by checking them first rather than time out on them then move onto the next computer in the list.

Could you show me how you are trying to find the other software. perhaps paste the code portion of the list of Software you ae looking for, then we can help work out what is going wrong.

Regards
Krystian



Option Explicit
 
 
	Call FindSoftware
 
Sub FindSoftware()
' Version 2.0 - Changed to get computers from a file
' Version 1.0
 
' Dated 17-Feb-2009
' Dated 16-Feb-2009
 
' Checks the list of machines if software
' is installed from a SW list  we provide
 
 
 
' Catch Errors Ourselves
	On Error Resume Next
 
' Declare Variables
	Dim fso, wshShell, wshEnv, objWMIService, oFile
	Dim strComputer, strResults, strProduct, sFileLocation
	Dim sInputFile, strHeader
	Dim colItems, objItem
	Dim arrSoftware
	Dim boolFound
 
	Dim strReadResults
	Dim arrComputers, i
 
	Const ForReading = 1	
	Const ForWriting = 2
	Const ForAppending = 8 
 
' ******************************************************************************************
' CHANGE THESE TO YOUR OWN SETTINGS
	
	sInputFile = "C:\ComputerList.txt"
	sFileLocation = "C:\Temp\Software_Output.csv"
 
' ******************************************************************************************
 
 
' Create Objects
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set wshShell = CreateObject("WScript.Shell")
 
 
' Create an array of software we want to look for
		arrSoftware = Array( _
			".NET Framework", _
			"McAfee", _
			"Lotus Notes" _
			)
 
 ' Create a header for the output file
	strHeader = "ComputerName"
		For Each strProduct In arrSoftware
			strHeader = strHeader & "," & strProduct
		Next
 	strHeader = strHeader & vbNewLine
 
' Open input File to get list of computers
	Set oFile = fso.OpenTextFile(sInputFile, ForReading, False)
	
	If Err.Number <> 0 Then
		WScript.Echo "Error reading File " & sInputFile
		Exit Sub
	End If
		
' Read the whole contents of the File
	Do While oFile.AtEndOfStream <> True
		strReadResults = oFile.ReadAll
	Loop
	
' Close the file
	oFile.Close
	
' Release the object from memory
	Set oFile = Nothing
	
' Return the contents of the file if not Empty
	If Trim(strReadResults) <> "" Then
		' Create an Array of the Text File
		arrComputers = Split(strReadResults, vbNewLine)
	End If
 
 
' Loop each computer
	For i = 0 To UBound(arrComputers)
		
		If arrComputers(i) = "" Then
			Exit For
		End If 
 
' Check if computer is online
		If Reachable(arrComputers(i)) = True Then 
 
		' Tell us which computer is being worked on			
			WScript.Echo arrComputers(i)
			
	' Start the output results
				strResults = strResults & arrComputers(i)
				
			Set objWMIService = GetObject("winmgmts:\\" & arrComputers(i) & "\root\cimv2")
			Set colItems = objWMIService.ExecQuery("Select Name, Version from Win32_Product")
				
				If Err.Number = 0 Then
		
					For Each strProduct In arrSoftware
						boolFound = False
		
						For Each objItem In colItems
							If InStr(LCase(objItem.Name), LCase(strProduct)) > 0 Then
								boolFound = True
								Exit For
							End If
						Next
		
							If boolFound = True Then
								strResults = strResults & ",Yes"
							Else
								strResults = strResults & ",No"
							End If
					Next
	
					' Put a new line at the  end of our results
						strResults = strResults & vbNewLine
	
				Else
					strResults = strResults & ",WMI Connection Error" & vbNewLine
					Err.Clear
				End If
		Else
			WScript.Echo arrComputers(i) & " Offline"
			strResults = strResults & arrComputers(i)
			strResults = strResults & ",Computer Offline" & vbNewLine
			Err.Clear
		End If 
	
	Next ' i
	
	
' Put a new line at the  end of our results
	strResults = strResults & vbNewLine
 
 
' ** WRITE RESULTS **
 
' If file exists then append the results, else we create the file and write the header and results
	If fso.FileExists(sFileLocation) = True Then 
		Set oFile = fso.OpenTextFile(sFileLocation, ForAppending, True)
 
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strResults)
	Else
		Set oFile = fso.OpenTextFile(sFileLocation, ForWriting, True)
		
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strHeader & strResults)
	End If 
 
 
' Close the file
	oFile.Close
 
' Release the object from memory
	Set oFile = Nothing
	Err.Clear
 
 
 
End Sub ' FindSoftware
 
 
 
Private Function Reachable(strComputer)
' Version 1.0
 
	On Error Resume Next
 
	Dim objPing, objStatus
 
	Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
		ExecQuery("select * from Win32_PingStatus where address = '" & strComputer & "'")
 
	For Each objStatus in objPing
		If IsNull(objStatus.StatusCode) Or objStatus.Statuscode <> 0 Then
			Reachable = False 'if computer is unreacable, return false
		Else
			Reachable = True 'if computer is reachable, return True
		End If
	Next
 
End Function 'Reachable
 
Function Ping(ByVal strName)
' Version 1.1
' Version 1.0
' Written by Krystian Karia
 
' Modified on 21-05-2005 - Improved the response
'	 Time and made the code more efficient
 
	Dim objFSO, objShell, objTempFile, objTS
	Dim sCommand, sReadAll
	Dim bReturn
	
	Set objShell = WScript.CreateObject("Wscript.Shell")
	Set objFSO = CreateObject("Scripting.FileSystemObject")
	
'Set default return value
	bReturn = False
	
'Create command line to ping and save results to a temp file
	sCommand = "cmd /c ping.exe -n 1 -w 750 " & strName & " > temp.txt"
	
'Execute the command
	objShell.run sCommand, 0, True
	
'Get the temp file
	Set objTempFile = objFSO.GetFile("temp.txt")
	Set objTS = objTempFile.OpenAsTextStream(1)
	
'Loop through the temp file to see if "reply from" is found,
'if it is then the ping was successful
 
    Do While objTS.AtEndOfStream <> True
        sReadAll = objTS.ReadAll
    Loop
 
'Close temp file
 
	objTS.Close
	objTempFile.Delete
 
'Check if a match is found
       
        If InStr(UCase(sReadAll), "TTL=") > 0 Then
            bReturn = True
        End If
    
'Release the objects
 
    Set objTS = Nothing
    Set objTempFile = Nothing
    Set objShell = Nothing
    Set objFSO = Nothing
	
 
'Return value
 
	Ping = bReturn
 
End Function

Open in new window

0
 
bsharathAuthor Commented:
I get this

C:\>cscript "Find 3 softwares Sophos.vbs"
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

dev-srv10

The csv does not populate with any data

These are the only 3 lines i changed

"Sophos Anti-Virus", _
      "Sophos AutoUpdate", _
      "Sophos Remote Management System" _
0
 
bsharathAuthor Commented:
I get this

C:\>cscript "Find 3 softwares Sophos.vbs"
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

dev-srv10

The csv does not populate with any data

These are the only 3 lines i changed

"Sophos Anti-Virus", _
      "Sophos AutoUpdate", _
      "Sophos Remote Management System" _
0
 
Krys_KCommented:
HI

Thats strange, i just ran the code again, but put your SW in my array and it ran and created the file with NO for all 3 (obviously)

does you r Aray look like this

arrSoftware = Array( _
       "Sophos Anti-Virus", _
      "Sophos AutoUpdate", _
      "Sophos Remote Management System" _
      )

Perhpas post the script you have amended and i can check if it runs for me (remove sensitive bits that i can change to suit for me)

Regards
Krystian
0
 
bsharathAuthor Commented:
Here is the full code
Option Explicit
 
 
	Call FindSoftware
 
Sub FindSoftware()
' Version 2.0 - Changed to get computers from a file
' Version 1.0
 
' Dated 17-Feb-2009
' Dated 16-Feb-2009
 
' Checks the list of machines if software
' is installed from a SW list  we provide
 
 
 
' Catch Errors Ourselves
	On Error Resume Next
 
' Declare Variables
	Dim fso, wshShell, wshEnv, objWMIService, oFile
	Dim strComputer, strResults, strProduct, sFileLocation
	Dim sInputFile, strHeader
	Dim colItems, objItem
	Dim arrSoftware
	Dim boolFound
 
	Dim strReadResults
	Dim arrComputers, i
 
	Const ForReading = 1	
	Const ForWriting = 2
	Const ForAppending = 8 
 
' ******************************************************************************************
' CHANGE THESE TO YOUR OWN SETTINGS
	
	sInputFile = "C:\Computers.txt"
	sFileLocation = "C:\Software_Output.csv"
 
' ******************************************************************************************
 
 
' Create Objects
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set wshShell = CreateObject("WScript.Shell")
 
 
' Create an array of software we want to look for
		arrSoftware = Array( _
			"Sophos Anti-Virus", _
	"Sophos AutoUpdate", _
	"Sophos Remote Management System" _
			)
 
 ' Create a header for the output file
	strHeader = "ComputerName"
		For Each strProduct In arrSoftware
			strHeader = strHeader & "," & strProduct
		Next
 	strHeader = strHeader & vbNewLine
 
' Open input File to get list of computers
	Set oFile = fso.OpenTextFile(sInputFile, ForReading, False)
	
	If Err.Number <> 0 Then
		WScript.Echo "Error reading File " & sInputFile
		Exit Sub
	End If
		
' Read the whole contents of the File
	Do While oFile.AtEndOfStream <> True
		strReadResults = oFile.ReadAll
	Loop
	
' Close the file
	oFile.Close
	
' Release the object from memory
	Set oFile = Nothing
	
' Return the contents of the file if not Empty
	If Trim(strReadResults) <> "" Then
		' Create an Array of the Text File
		arrComputers = Split(strReadResults, vbNewLine)
	End If
 
 
' Loop each computer
	For i = 0 To UBound(arrComputers)
		
		If arrComputers(i) = "" Then
			Exit For
		End If 
 
' Check if computer is online
		If Reachable(arrComputers(i)) = True Then 
 
		' Tell us which computer is being worked on			
			WScript.Echo arrComputers(i)
			
	' Start the output results
				strResults = strResults & arrComputers(i)
				
			Set objWMIService = GetObject("winmgmts:\\" & arrComputers(i) & "\root\cimv2")
			Set colItems = objWMIService.ExecQuery("Select Name, Version from Win32_Product")
				
				If Err.Number = 0 Then
		
					For Each strProduct In arrSoftware
						boolFound = False
		
						For Each objItem In colItems
							If InStr(LCase(objItem.Name), LCase(strProduct)) > 0 Then
								boolFound = True
								Exit For
							End If
						Next
		
							If boolFound = True Then
								strResults = strResults & ",Yes"
							Else
								strResults = strResults & ",No"
							End If
					Next
	
					' Put a new line at the  end of our results
						strResults = strResults & vbNewLine
	
				Else
					strResults = strResults & ",WMI Connection Error" & vbNewLine
					Err.Clear
				End If
		Else
			WScript.Echo arrComputers(i) & " Offline"
			strResults = strResults & arrComputers(i)
			strResults = strResults & ",Computer Offline" & vbNewLine
			Err.Clear
		End If 
	
	Next ' i
	
	
' Put a new line at the  end of our results
	strResults = strResults & vbNewLine
 
 
' ** WRITE RESULTS **
 
' If file exists then append the results, else we create the file and write the header and results
	If fso.FileExists(sFileLocation) = True Then 
		Set oFile = fso.OpenTextFile(sFileLocation, ForAppending, True)
 
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strResults)
	Else
		Set oFile = fso.OpenTextFile(sFileLocation, ForWriting, True)
		
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strHeader & strResults)
	End If 
 
 
' Close the file
	oFile.Close
 
' Release the object from memory
	Set oFile = Nothing
	Err.Clear
 
 
 
End Sub ' FindSoftware
 
 
 
Private Function Reachable(strComputer)
' Version 1.0
 
	On Error Resume Next
 
	Dim objPing, objStatus
 
	Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
		ExecQuery("select * from Win32_PingStatus where address = '" & strComputer & "'")
 
	For Each objStatus in objPing
		If IsNull(objStatus.StatusCode) Or objStatus.Statuscode <> 0 Then
			Reachable = False 'if computer is unreacable, return false
		Else
			Reachable = True 'if computer is reachable, return True
		End If
	Next
 
End Function 'Reachable
 
Function Ping(ByVal strName)
' Version 1.1
' Version 1.0
' Written by Krystian Karia
 
' Modified on 21-05-2005 - Improved the response
'	 Time and made the code more efficient
 
	Dim objFSO, objShell, objTempFile, objTS
	Dim sCommand, sReadAll
	Dim bReturn
	
	Set objShell = WScript.CreateObject("Wscript.Shell")
	Set objFSO = CreateObject("Scripting.FileSystemObject")
	
'Set default return value
	bReturn = False
	
'Create command line to ping and save results to a temp file
	sCommand = "cmd /c ping.exe -n 1 -w 750 " & strName & " > temp.txt"
	
'Execute the command
	objShell.run sCommand, 0, True
	
'Get the temp file
	Set objTempFile = objFSO.GetFile("temp.txt")
	Set objTS = objTempFile.OpenAsTextStream(1)
	
'Loop through the temp file to see if "reply from" is found,
'if it is then the ping was successful
 
    Do While objTS.AtEndOfStream <> True
        sReadAll = objTS.ReadAll
    Loop
 
'Close temp file
 
	objTS.Close
	objTempFile.Delete
 
'Check if a match is found
       
        If InStr(UCase(sReadAll), "TTL=") > 0 Then
            bReturn = True
        End If
    
'Release the objects
 
    Set objTS = Nothing
    Set objTempFile = Nothing
    Set objShell = Nothing
    Set objFSO = Nothing
	
 
'Return value
 
	Ping = bReturn
 
End Function

Open in new window

0
 
bsharathAuthor Commented:
Here is the full code
Option Explicit
 
 
	Call FindSoftware
 
Sub FindSoftware()
' Version 2.0 - Changed to get computers from a file
' Version 1.0
 
' Dated 17-Feb-2009
' Dated 16-Feb-2009
 
' Checks the list of machines if software
' is installed from a SW list  we provide
 
 
 
' Catch Errors Ourselves
	On Error Resume Next
 
' Declare Variables
	Dim fso, wshShell, wshEnv, objWMIService, oFile
	Dim strComputer, strResults, strProduct, sFileLocation
	Dim sInputFile, strHeader
	Dim colItems, objItem
	Dim arrSoftware
	Dim boolFound
 
	Dim strReadResults
	Dim arrComputers, i
 
	Const ForReading = 1	
	Const ForWriting = 2
	Const ForAppending = 8 
 
' ******************************************************************************************
' CHANGE THESE TO YOUR OWN SETTINGS
	
	sInputFile = "C:\Computers.txt"
	sFileLocation = "C:\Software_Output.csv"
 
' ******************************************************************************************
 
 
' Create Objects
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set wshShell = CreateObject("WScript.Shell")
 
 
' Create an array of software we want to look for
		arrSoftware = Array( _
			"Sophos Anti-Virus", _
	"Sophos AutoUpdate", _
	"Sophos Remote Management System" _
			)
 
 ' Create a header for the output file
	strHeader = "ComputerName"
		For Each strProduct In arrSoftware
			strHeader = strHeader & "," & strProduct
		Next
 	strHeader = strHeader & vbNewLine
 
' Open input File to get list of computers
	Set oFile = fso.OpenTextFile(sInputFile, ForReading, False)
	
	If Err.Number <> 0 Then
		WScript.Echo "Error reading File " & sInputFile
		Exit Sub
	End If
		
' Read the whole contents of the File
	Do While oFile.AtEndOfStream <> True
		strReadResults = oFile.ReadAll
	Loop
	
' Close the file
	oFile.Close
	
' Release the object from memory
	Set oFile = Nothing
	
' Return the contents of the file if not Empty
	If Trim(strReadResults) <> "" Then
		' Create an Array of the Text File
		arrComputers = Split(strReadResults, vbNewLine)
	End If
 
 
' Loop each computer
	For i = 0 To UBound(arrComputers)
		
		If arrComputers(i) = "" Then
			Exit For
		End If 
 
' Check if computer is online
		If Reachable(arrComputers(i)) = True Then 
 
		' Tell us which computer is being worked on			
			WScript.Echo arrComputers(i)
			
	' Start the output results
				strResults = strResults & arrComputers(i)
				
			Set objWMIService = GetObject("winmgmts:\\" & arrComputers(i) & "\root\cimv2")
			Set colItems = objWMIService.ExecQuery("Select Name, Version from Win32_Product")
				
				If Err.Number = 0 Then
		
					For Each strProduct In arrSoftware
						boolFound = False
		
						For Each objItem In colItems
							If InStr(LCase(objItem.Name), LCase(strProduct)) > 0 Then
								boolFound = True
								Exit For
							End If
						Next
		
							If boolFound = True Then
								strResults = strResults & ",Yes"
							Else
								strResults = strResults & ",No"
							End If
					Next
	
					' Put a new line at the  end of our results
						strResults = strResults & vbNewLine
	
				Else
					strResults = strResults & ",WMI Connection Error" & vbNewLine
					Err.Clear
				End If
		Else
			WScript.Echo arrComputers(i) & " Offline"
			strResults = strResults & arrComputers(i)
			strResults = strResults & ",Computer Offline" & vbNewLine
			Err.Clear
		End If 
	
	Next ' i
	
	
' Put a new line at the  end of our results
	strResults = strResults & vbNewLine
 
 
' ** WRITE RESULTS **
 
' If file exists then append the results, else we create the file and write the header and results
	If fso.FileExists(sFileLocation) = True Then 
		Set oFile = fso.OpenTextFile(sFileLocation, ForAppending, True)
 
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strResults)
	Else
		Set oFile = fso.OpenTextFile(sFileLocation, ForWriting, True)
		
			If Err.Number <> 0 Then
'				WScript.Echo "Error opening file: " & strOutputFile
				Exit Sub 
			End If
			
			oFile.Write(strHeader & strResults)
	End If 
 
 
' Close the file
	oFile.Close
 
' Release the object from memory
	Set oFile = Nothing
	Err.Clear
 
 
 
End Sub ' FindSoftware
 
 
 
Private Function Reachable(strComputer)
' Version 1.0
 
	On Error Resume Next
 
	Dim objPing, objStatus
 
	Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
		ExecQuery("select * from Win32_PingStatus where address = '" & strComputer & "'")
 
	For Each objStatus in objPing
		If IsNull(objStatus.StatusCode) Or objStatus.Statuscode <> 0 Then
			Reachable = False 'if computer is unreacable, return false
		Else
			Reachable = True 'if computer is reachable, return True
		End If
	Next
 
End Function 'Reachable
 
Function Ping(ByVal strName)
' Version 1.1
' Version 1.0
' Written by Krystian Karia
 
' Modified on 21-05-2005 - Improved the response
'	 Time and made the code more efficient
 
	Dim objFSO, objShell, objTempFile, objTS
	Dim sCommand, sReadAll
	Dim bReturn
	
	Set objShell = WScript.CreateObject("Wscript.Shell")
	Set objFSO = CreateObject("Scripting.FileSystemObject")
	
'Set default return value
	bReturn = False
	
'Create command line to ping and save results to a temp file
	sCommand = "cmd /c ping.exe -n 1 -w 750 " & strName & " > temp.txt"
	
'Execute the command
	objShell.run sCommand, 0, True
	
'Get the temp file
	Set objTempFile = objFSO.GetFile("temp.txt")
	Set objTS = objTempFile.OpenAsTextStream(1)
	
'Loop through the temp file to see if "reply from" is found,
'if it is then the ping was successful
 
    Do While objTS.AtEndOfStream <> True
        sReadAll = objTS.ReadAll
    Loop
 
'Close temp file
 
	objTS.Close
	objTempFile.Delete
 
'Check if a match is found
       
        If InStr(UCase(sReadAll), "TTL=") > 0 Then
            bReturn = True
        End If
    
'Release the objects
 
    Set objTS = Nothing
    Set objTempFile = Nothing
    Set objShell = Nothing
    Set objFSO = Nothing
	
 
'Return value
 
	Ping = bReturn
 
End Function

Open in new window

0
 
Krys_KCommented:
Hi Thanks

I ran your script exactly as you gave it to me and it worked perfectly.
The output file was put in C but it was right near the top for some reason - took me a moment to find it.

If you comment out the
On Error Resume Next

Do you get any errors??

Krystian
0
 
bsharathAuthor Commented:
Yes i get this error when i comment the line

---------------------------
Windows Script Host
---------------------------
Script:      C:\Find 3 softwares Sophos.vbs
Line:      114
Char:      7
Error:      0x80041010
Code:      80041010
Source:       (null)

---------------------------
OK  
---------------------------
0
 
bsharathAuthor Commented:
Yes i get this error when i comment the line

---------------------------
Windows Script Host
---------------------------
Script:      C:\Find 3 softwares Sophos.vbs
Line:      114
Char:      7
Error:      0x80041010
Code:      80041010
Source:       (null)

---------------------------
OK  
---------------------------
0
 
Krys_KCommented:
Hi

Can you delete Line 106
and replace it with this one

That old line was a hang over from the original script you were given.

Hope it helps

Krystian
Set objWMIService = GetObject("winmgmts:" _
	& "{impersonationLevel=impersonate}!//" & arrComputers(i) & "\root\cimv2")

Open in new window

0
 
bsharathAuthor Commented:
I get this now

---------------------------
Windows Script Host
---------------------------
Script:      C:\Find 3 softwares Sophos.vbs
Line:      116
Char:      7
Error:      0x80041010
Code:      80041010
Source:       (null)

---------------------------
OK  
---------------------------
0
 
Krys_KCommented:
I just realised!

On that machine you may not have the WMI Windows Installer Provider installed.

Go to Add/remove Programs -> Windows Components
Management and Monitoring tools -> Details
is the "WMI Windows Installer Provider" installed ??

Its not by default on XP or Win2k3 Servers which is very annoying!
You may find some machines have it installed and others don't

There is a way to install this feature on all remote machines but it escapes me right now.

I will need to find the details again on how to do this.

Krystian

PS
You can uncomment the On Error... now we know what the error is.

0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 22
  • 9
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now