![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | VBS to list machines with specific software Hey, Does anyone know of a script which essentially outputs a list of machines on a network domain, with specific software installed. For example, list all machines on the network domain with 'Google Talk' installed, or 'Photoshop' etc. I've been working on something but I can't get it to work accordingly. Think I'm going down the wrong route all together! |
My System Specs![]() |
| | #2 (permalink) |
| | RE: VBS to list machines with specific software I was checking the status of my post and noticed your's here and thought I'd "give a little something back" to the group. Hope this code helps. It may seem like I've taken the long way 'round the barn, but I reuse a lot of my modules so it's easier to build something kinda generic and reuse it, which is what I've done. Note that this will prompt for any input file (if it's appropriately named SoftwareSearch_whatever_Input.txt) The underscore whatever is optional too. You should list the exact names of the software you are searching for, and the systems (FQDN ok) to search, in the text file. It reports to Excel, so you might want to rewrite that portion to comma delim or text if you don't have XL installed. Good luck and hope this helps. ' *********************** ' SoftwareSearch.vbs ' Vers 08/10/09 ' by M. O'Neal @ BPA ' *********************** ' ' Search all systems in _Input.txt file for specific software. On Error Resume Next ' Needed in any routine that uses the Err. object test '****************************************************************************** ' Program constants & variables Public PROGRAM PROGRAM = Left(WScript.ScriptName, Len(WScript.ScriptName)-4) ' Remove .vbs extension Public Const LogFormatted = True ' Set whether to log formatted messages Public Const LogScreen = False ' Log to the screen instead of file, if True Public Const LogNothing = 0 ' "log no messages" flag Public Const LogNormal = 1 ' "log normal messages" flag Public Const LogDebug = 2 ' "log normal & debug messages" flag Public VerboseLevel ' Set to flag level above ' Any non-zero value causes logging VerboseLevel = LogNormal ' Set the logging verbosity level '****************************************************************************** ' OFN constants Public Const OFN_ALLOWMULTISELECT = &H200 ' multiple file selections; use only with Open. OFN_EXPLORER must also be set. Public Const OFN_CREATEPROMPT = &H2000 ' prompt to create a file that doesn't exist. sets OFN_PATHMUSTEXIST. Works only with Open. Public Const OFN_ENABLEHOOK = &H20 ' Enables the Hook function specified in the lpfnHook member Public Const OFN_ENABLETEMPLATE = &H40 ' Indicates that the lpTemplateName member is a pointer to the name of a dialog box template resource in the module identified by the hInstance member Public Const OFN_EXPLORER = &H80000 ' Explorer-style dialog boxes. Automatically set, but must specifically be set if OFN_ALLOWMULTISELECT is used. Public Const OFN_EXTENSIONDIFFERENT = &H400 ' On return, specifies that the user typed a file name extension that differs from the extension specified by lpstrDefExt. Not used if lpstrDefExt is unspecified. Public Const OFN_FILEMUSTEXIST = &H1000 ' Accepts only existing file. Works only with Open. Public Const OFN_HIDEREADONLY = &H4 ' Hides the read-only box. Should be set for Save As. Public Const OFN_LONGNAMES = &H200000 ' Explorer-style dialog boxes ignore this flag and always display long file names. Public Const OFN_NOCHANGEDIR = &H8 ' Restores the current directory to its original value if the user changed the directory while searching for files. Public Const OFN_NODEREFERENCELINKS = &H100000 ' Returns the path and file name of the selected shortcut (.lnk) file. If not specified, the dialog box returns the path and file name of the file referenced by the shortcut. Public Const OFN_OVERWRITEPROMPT = &H2 ' In the Save As dialog box, display a message box if the selected file already exists. The user must confirm whether to overwrite the file. Public Const OFN_PATHMUSTEXIST = &H800 ' Accepts only existing path. Public Const OFN_READONLY = &H1 ' Selects the read-only check box when the dialog box is created. Returns the state of the read-only check box when the dialog box is closed. Only useful with Open. Public Const OFN_TEST = &H600 ' NoNewFolder button ??? Public Const OFN_SHOWHELP = &H10 ' '****************************************************************************** ' fso constants Public Const FOR_READING = 1 Public Const FOR_WRITING = 2 Public Const FOR_APPENDING = 8 Public Const Create = True 'Create the file if it doesn't exist Public Const NoCreate = False 'Don't create the file if it doesn't exist Public Const OVERWRITE_EXISTING = True ' (vbTrue can't be used here) Public objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject") '****************************************************************************** ' Set AppPath to the current drive & directory, otherwise Windows ' uses C:\WINNT\system32 (ugh!) as the current directory. Public AppPath AppPath = objFSO.GetParentFolderName(Wscript.ScriptFullName) '****************************************************************************** 'Definable parms Public Const LogDir = "" Public Const LogExt = "_log.txt" ' Log file extensions Public Const inputExt = "_Input.txt" ' Input text data file '****************************************************************************** ' Registry constants const HKEY_CLASSES_ROOT = &H80000000 const HKEY_CURRENT_USER = &H80000001 const HKEY_LOCAL_MACHINE = &H80000002 const HKEY_USERS = &H80000003 const HKEY_CURRENT_CONFIG = &H80000005 const REG_SZ = 1 const REG_EXPAND_SZ = 2 const REG_BINARY = 3 const REG_DWORD = 4 const REG_MULTI_SZ = 7 '****************************************************************************** 'Use the vbscript "Dictionary" object as a collection Set Software = CreateObject("Scripting.Dictionary") Set Servers = CreateObject("Scripting.Dictionary") CaseSensitive = vbFalse ' software names compare ' Create a program log x = OpenLog( PROGRAM , objProgLog, FOR_WRITING) If NOT x Then WScript.Echo "Unable to create program log." WScript.Sleep 5000 WScript.Quit(1) End If '------------------------------------------------------------------------------ 'Read the server list file - Load the lists '------------------------------------------------------------------------------ iFile = BrowseForFile(AppPath, "Input Files|*" & inputExt) msg = "Reading input file: " & Program & inputExt x = ProgLog(msg, LogNormal) WScript.Echo msg WScript.Echo "This might take a minute or two to complete." Err.Clear Set InputFile = OpenFile(iFile, FOR_READING, NoCreate) If Err.Number<>0 Then x = ProgLog(FormatErr(Err),LogNormal) WScript.Quit(0) ' Set above will return err object End If Do Until InputFile.AtEndOfStream x = GetLine(InputFile) If x = "#" Then Exit Do If x <> "" Then Software.Add x, x Loop Do Until InputFile.AtEndOfStream x = UCase(GetLine(InputFile)) If x <> "" Then Servers.Add x, x Loop InputFile.Close '------------------------------------------------------------------------------ ' Create the CSV report file '------------------------------------------------------------------------------ 'Create a timestamp to make this file unique TheTime = Now strTime = PadTime(Year(TheTime)) & PadTime(Month(TheTime)) & PadTime(Day(TheTime)) Err.Clear ReportFilename = Append( Append(AppPath, LogDir), PROGRAM & "_" & strTime & "_report.csv") Set ReportFile = OpenFile(ReportFilename, FOR_WRITING, Create) If Err.Number<>0 Then WScript.Quit(0) ' Set above will return err object ' Create the report file headding - the names of the software ReportFile.WriteLine ", " & Join(Software.Keys, ",") '------------------------------------------------------------------------------ 'Loop on all Servers '------------------------------------------------------------------------------ For Each strComputer in Servers WScript.Echo strComputer x = ProgLog("", LogNormal) x = ProgLog(String(72, "-"), LogNormal) x = ProgLog(strComputer, LogNormal) x = ProgLog(String(72, "-"), LogNormal) '------------------------------------------------------------------------------ '* Connect to WMI Service. '------------------------------------------------------------------------------ Err.Clear Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer ) If Err.Number <> 0 Then ' trouble connection to strComputer's WMI x = ProgLog(FormatErr(Err), LogNormal) x = ProgLog("Unable to connect to WMI. WMI may not be properly installed on " & strComputer, LogNormal) Err.Clear Else ' let's go get this node's info ' Reset software array items (software versions) For Each strKey in Software.Keys Software.Item(strkey) = "" ' *not installed* Next ' Access the registry (using WMI) Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & _ "\root\default:StdRegProv") strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, InstalledSoftware ' Loop through all "Uninstallable" software For Each strSubkey In InstalledSoftware iRet = oReg.GetStringValue(HKEY_LOCAL_MACHINE, strKeyPath & strSubkey, _ "DisplayName", InstalledProgram) If iRet<>0 Then oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & strSubkey, _ "QuietDisplayName", InstalledProgram End If If InstalledProgram<>"" Then ' found a program 'WScript.Echo " " & InstalledProgram 'debug purposes For Each ProgramToFind in Software ' Was this a program of interest? If RegExTest(InstalledProgram, ProgramToFind, CaseSensitive) Then oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & strSubkey, _ "DisplayVersion", Version oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & strSubkey, _ "Publisher", Vendor 'Below is a different reporting style 'ReportFile.WriteLine strComputer & ", " & Vendor & ", " & InstalledProgram & ", " & Version x = ProgLog(" Found: " & Vendor & " - " & InstalledProgram & _ " - " & Version, LogNormal) If Version="" OR IsNull(Version) Then Version="-unknown-" Software.Item(ProgramToFind) = Version ' remember the version for reporting 'Excel interprets 6.0 in a CSV as 6 - Perhaps preserve the 0 with period End If ' program of interest Next ' program to find in software End If ' InstalledProgram<>"" Next ' Uninstallable software ' Report the software version information ReportFile.WriteLine strComputer & ", " & Join(Software.Items, ",") End If ' strComputer WMI connection test Next ' End of strComputer loop on all servers ReportFile.Close ' close the report file x = ProgLog("", LogNormal) x = ProgLog(String(72, "-"), LogNormal) '------------------------------------------------------------------------------ x = CloseLog(objProgLog) Set objFSO = Nothing WScript.Echo "Done - Software information retrieved." ' Open the file up in notepad Set objShell = CreateObject("Wscript.Shell") 'iErrorCode = objShell.Run("notepad.exe " & PROGRAM & LogExt,,False) iErrorCode = objShell.Run(ReportFilename,,False) 'END of program '|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| '****************************************************************************** Function BrowseForFile(pstrPath, pstrFilter) ' OFN Dialog Set objDialog = CreateObject("MSComDlg.CommonDialog") objDialog.Filter = pstrFilter objDialog.InitDir = pstrPath objDialog.MaxFileSize = 256 objDialog.Flags = OFN_EXPLORER + OFN_FILEMUSTEXIST + OFN_NOCHANGEDIR + OFN_HIDEREADONLY intResult = objDialog.ShowOpen() BrowseForFile = objDialog.FileName End Function '****************************************************************************** Function PadTime(TheTime) ' Add a leading zero to times less than 10 If Len(TheTime) < 2 Then PadTime = "0" & TheTime Else PadTime = TheTime End If End Function '****************************************************************************** Function GetLine(objTextFile) '****************************************************************************** 'GetLine from objTextFile (and ignore any comments) GetLine = "" ' sort-of-like "assume the worst" (return blank) CommentStr = "'!" ' apostrophy and exclamation are comments Do Until objTextFile.AtEndOfStream L = Trim(objTextFile.Readline) 'Read a line (dissregard any leadding spaces) ' Look for and skip any comment lines (based on leftmost character) Chr1 = Left(L,1) 'Get the left most character of the line read from the file If InStr(CommentStr, Chr1)=0 Then ' it's comment free! GetLine = L ' It ok to return this line to caller Exit Function End If Loop ' Get another line End Function '****************************************************************************** Function Append(str1, str2) '****************************************************************************** ' Concatenate strings str1 and str2 with a single delimiter in between ' If they didn't specify a delimiter, assume backslash (future) If Delim ="" then Delim ="\" LD = Len(Delim) 'Test for delimiters d1 = (Right(str1,LD) = Delim) ' Right most chr(s) of string 1 a delim? d2 = (Left(str2,LD) = Delim) ' Left most chr(s) of string 2 a delim? If d1 and d2 Then 'both have delims, remove one delimiter Append = Left(str1, Len(str1)-LD) & str2 ElseIf NOT d1 and NOT d2 Then 'neither has a delim, add a delimiter Append = str1 & Delim & str2 Else 'only one of them has a delimiter, so don't worry about it Append = str1 & str2 End If End Function '****************************************************************************** Function RegExTest(SearchStr, pattern, CaseSensitive) 'as Logical '****************************************************************************** ' Returns TRUE if 'pattern' regular expression appears in 'SearchStr' Dim regEx ' Create regEx object Set regEx = New RegExp ' Make object a reg exp type regEx.Pattern = pattern ' Set pattern regEx.IgnoreCase = NOT(CaseSensitive) RegExTest = regEx.Test(SearchStr) ' Execute the search test str = "RegEx test for " & pattern & " in " & SearchStr & " = " & RegExTest If CaseSensitive Then str = "Case sensitive " & str z = ProgLog(str, LogDebug) End Function '****************************************************************************** Function OpenFile(strMyFile, RW_Mode, CreateMode) '****************************************************************************** On Error Resume Next ' Needed in any routine that uses the Err. object test If RW_Mode = FOR_READING Then strMode = "reading" ElseIf RW_Mode = FOR_WRITING Then strMode = "writing" ElseIf RW_Mode = FOR_APPENDING Then strMode = "appending" Else strMode = "unknown r/w mode" End If Err.Clear Set OpenFile = objFSO.OpenTextFile (strMyFile, RW_Mode, CreateMode) If Err.Number<>0 Then x = ProgLog("", LogNormal) x = ProgLog("Could not open " & strMyFile & " for " & strMode , LogNormal) 'WScript.Echo "Could not open " & strMyFile & " for " & strMode Else x = ProgLog("", LogDebug) x = ProgLog("Opened " & strMyFile & " for " & strMode, LogDebug) End If End Function '****************************************************************************** ' LOG FILE FUNCTIONS '****************************************************************************** '****************************************************************************** Function OpenLog(strMyFile, objTextFile, Mode) '****************************************************************************** 'Create(if necessary) & open the specified log for writting or appending On Error Resume Next ' Needed in any routine that uses the Err. object test OpenLog = vbFalse 'assume the worst If LogScreen then 'they don't even want a log OpenLog = vbTrue 'fake it and return ElseIf VerboseLevel Then If Mode=FOR_WRITING OR Mode=FOR_APPENDING Then ' Build the full path and filename strFile = Append( Append(AppPath, LogDir), strMyFile & LogExt) Err.Clear Set objTextFile = objFSO.OpenTextFile (strFile, Mode, Create) If Err.Number = 0 Then objTextFile.WriteLine "<<< LOG OPENED AT " & Now & " >>>" objTextFile.WriteBlankLines(1) objTextFile.WriteLine "VerboseLevel = " & VerboseLevel OpenLog = vbTrue Else 'CreateLog didn't work - rats, how do we tell them WScript.Echo "Unable to create log: " & strFile End If End If End If End Function '****************************************************************************** Function CloseLog(objTextFile) '****************************************************************************** If VerboseLevel AND Not(LogScreen) Then objTextFile.WriteBlankLines(1) objTextFile.WriteLine "<<< LOG CLOSED AT " & Now & " >>>" objTextFile.WriteBlankLines(1) objTextFile.Close Set objTextFile = Nothing End If End Function '****************************************************************************** Function ProgLog(msg, msgLevel) '****************************************************************************** 'Logs msg to the program log On Error Resume Next ' Needed in any routine that uses the Err. object test If VerboseLevel => msgLevel Then If LogFormatted Then str = FormatMsg(msg) Else str = msg End If Err.Clear If LogScreen Then WScript.Echo str Else objProgLog.WriteLine str End If If Err.Number = 0 Then ProgLog = vbTrue Else ProgLog = vbFalse WScript.Echo "Unable to log message: " & msg End If End If End Function '****************************************************************************** Function FormatMsg(str) '****************************************************************************** ' Format message for logging and message box display FormatMsg = " " & Now & " | " & str End Function '****************************************************************************** Function FormatErr(objErr) '****************************************************************************** FormatErr = " ...Error 0x" & hex(objErr.Number) & " Source = " & objErr.Source &_ vbCrLf & space(26) & " - " & objErr.Description End Function -- It''s my faults that keep me humble "Mike Fairbrother" wrote: Quote: > Hey, > > Does anyone know of a script which essentially outputs a list of > machines on a network domain, with specific software installed. > > For example, list all machines on the network domain with 'Google > Talk' installed, or 'Photoshop' etc. > > I've been working on something but I can't get it to work accordingly. > Think I'm going down the wrong route all together! > |
My System Specs![]() |
| | #3 (permalink) |
| | RE: VBS to list machines with specific software Here's a sample input file. Save the text below as: "SoftwareSearch_MyList_Input.txt" '************************************************ ' Software Search Input file '************************************************ '----------------------- ' Software to search for '----------------------- ActivePerl Adobe Reader Java MSXML 'Studio 2005 ' not installed VC++ SourceSafe Word Viewer # '------------------- ' Systems to search '------------------- Cons1 ' Terry Cons2 ' Paul Dis1.asr.site.com ' Sherry Dis2.asr.site.com ' Done Dis3.asr.site.com ' Mark -- It''s my faults that keep me humble "Mike Fairbrother" wrote: Quote: > Hey, > > Does anyone know of a script which essentially outputs a list of > machines on a network domain, with specific software installed. > > For example, list all machines on the network domain with 'Google > Talk' installed, or 'Photoshop' etc. > > I've been working on something but I can't get it to work accordingly. > Think I'm going down the wrong route all together! > |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| Change the listing color in the message list pane from specific e- | Vista mail | |||
| List SPN of a specific AD object? | PowerShell | |||
| list the machines I can connect to via remote desktop. | VB Script | |||
| VBScript to list PST files and their location on a specific drive ona PC to a CSV file | VB Script | |||
| How do you run a Power Shell Script against a list of machines? | PowerShell | |||