Option Explicit Dim blnLiteral, blnRegEx, blnValid Dim i Dim objFile, objFSO, objMSI, objMSIDB, objRE Dim strAllContent, strFolder, strFilter, strLine, strResult Const msiOpenDatabaseModeReadOnly = 0 Const msiOpenDatabaseModeTransact = 1 Const msiOpenDatabaseModeListScript = 5 strFilter = "" blnLiteral = False blnRegEx = False With WScript.Arguments If .Unnamed.Count = 0 Then Syntax If .Unnamed.Count > 0 Then strFolder = .Unnamed(0) End If If .Unnamed.Count > 1 Then Syntax If .Named.Count = 1 Then If .Named.Exists( "R" ) Then blnRegEx = True strFilter = .Named( "R" ) ElseIf .Named.Exists( "F" ) Then blnLiteral = True strFilter = .Named( "F" ) Else Syntax End If End If If .Named.Count > 1 Then Syntax End With Set objFSO = CreateObject( "Scripting.FileSystemObject" ) Set objMSI = CreateObject( "WindowsInstaller.Installer" ) If blnRegEx Then Set objRE = New RegExp objRE.Pattern = strFilter objRE.IgnoreCase = True End If With objFSO If .FolderExists( strFolder ) Then strAllContent = SearchFolder( strFolder, "msi" ) strResult = "" For Each strLine In Split( strAllContent, vbCrLf ) blnValid = False If Trim( strLine ) <> "" Then If blnLiteral Then If InStr( LCase( Split( strLine, vbTab )(1) ), LCase( strFilter ) ) Then blnValid = True End If ElseIf blnRegEx Then If objRE.Test( Split( strLine, vbTab )(1) ) Then blnValid = True End If Else blnValid = True End If If blnValid Then strResult = strResult & strLine & vbCrLf End If Next Else Syntax End If End With WScript.Echo strResult Set objRE = Nothing Set objFSO = Nothing Set objMSI = Nothing Sub CheckError Dim strMsg, strErrorRecord If Err = 0 Then Exit Sub strMsg = Err.Source & " " & Hex(Err) & ": " & Err.Description If Not installer Is Nothing Then Set strErrorRecord = installer.LastErrorRecord If Not strErrorRecord Is Nothing Then strMsg = strMsg & vbCrLf & strErrorRecord.FormatText End If End If Wscript.Echo strMsg Wscript.Quit 2 End Sub Function SearchFolder( strFolder, strExt ) SearchFolder = "" Dim objFile, objFolder, strResult For Each objFile In objFSO.GetFolder( strFolder ).Files If LCase( objFSO.GetExtensionName( objFile.Name ) ) = LCase( strExt ) Then strResult = strResult & ViewMSIFile( objFile.Path ) & vbCrLf End If Next For Each objFolder In objFSO.GetFolder( strFolder ).SubFolders strResult = strResult & SearchFolder( objFolder.Path, strExt ) & vbCrLf Next SearchFolder = strResult End Function Function ViewMSIFile( strMSIFile ) Dim objMSIDB, objRecord, objView, strResult ViewMSIFile = "" Set objMSIDB = objMSI.OpenDataBase( strMSIFile, msiOpenDatabaseModeReadOnly ) : CheckError Set objView = objMsiDB.Openview( "Select FileName From File" ) : CheckError objView.Execute : CheckError Set objRecord = objView.Fetch strResult = "" Do Until objRecord Is Nothing If InStr( objRecord.StringData(1), "|" ) Then strResult = strResult & strMSIFile & vbTab & Split( objRecord.StringData(1), "|" )(1) & vbCrLf Else strResult = strResult & strMSIFile & vbTab & objRecord.StringData(1) End If Set objRecord = objView.Fetch Loop Set objRecord = Nothing Set objView = Nothing Set objMSIDB = Nothing ViewMSIFile = strResult End Function Sub Syntax Dim strMsg strMsg = vbCrLf _ & "SearchMSIs.vbs, Version 1.01\n" _ & "List all MSI files in a folder and its subfolders,\n" _ & "and optionally search them for the specified file(s).\n\n" _ & "Usage: CSCRIPT.EXE //NoLogo SearchMSIs.vbs folder [ /F:file | /R:regex ]\n\n" _ & "Where: folder is the ""root"" folder where the search starts\n" _ & " /F:file specifies (part of) the file name(s) to search for (literal)\n" _ & " /R:regex like /F:file, but using a regular expression instead of\n" _ & " a literal search string\n\n" _ & "Note: DO use CSCRIPT.EXE rather than WSCRIPT.EXE, as the latter MAY\n" _ & " not be able to handle the huge amount of output.\n\n" _ & "Credits: Based on ListMSI.vbs by Adriaan Westra\n" _ & " http://www.westphil.nl/content/index.php?\n" _ & " option=com_content&view=article&id=46&Itemid=64\n\n" _ & "Example: Find all MSI files in D:\WDK or its subfolders containing *devcon*\n" _ & " CSCRIPT.EXE //NoLogo SearchMSIs.vbs D:\WDK /F:devcon\n\n" _ & "Resulting output:\n" _ & " D:\WDK\setupsamples.msi devcon.cpp\n" _ & " D:\WDK\setupsamples.msi devcon.h\n" _ & " D:\WDK\setupsamples.msi devcon.htm\n" _ & " D:\WDK\setupsamples.msi devcon.rc\n" _ & " D:\WDK\setuptools_ia64fre.msi devcon.exe\n" _ & " D:\WDK\setuptools_x64fre.msi devcon.exe\n" _ & " D:\WDK\setuptools_x86fre.msi devcon.exe\n\n" _ & "Written by Rob van der Woude\n" _ & "http://www.robvanderwoude.com" WScript.Echo Replace( strMsg, "\n", vbCrLf ) On Error Resume Next Set objRE = Nothing Set objFSO = Nothing Set objMSI = Nothing On Error Goto 0 WScript.Quit 1 End Sub