' search.vbs
'
' This proc does "advanced" file search via the Windows Search database.
' Adapted from http://technet.microsoft.com/en-us/library/ff404224.aspx
' Searchable properties list: http://technet.microsoft.com/en-us/library/ff404235.aspx
' The tool does not search for text within files. This is done nicely by Google Desktop Search.
'
' Usage: cscript/nologo search.vbs filename | filename.* | *.extension [-q] [> outputfile]
'
' Note: This tool requires local disks to search to be indexed with the Windows Search Service.
'
' Input       : file specification
' Output      : fully qualified list
' Side effects: none
'
' v1.0-0 27-oct-2010 DTL Didier.Morandi at gmail.com http://www.scripting-errors.com/
' v2.0-0  7-nov-2010 DTL add wildcards processing

Option Explicit

Dim objConnection, objRecordSet, objCommand
Dim intNbFiles, intSize
Dim iStart, iSTop
Dim strTarget, strKey
Dim blnQuiet

blnQuiet = False
intNbFiles = 0
intSize = ""
strKey = ""

if wscript.arguments.count = 0 then
  wscript.echo _
         "Syntax: search filename | filename.* | *.extension [-q] [> outputfile]"
  wscript.quit

elseif wscript.arguments.count = 1 then
  if wscript.arguments(0) = "/?" then 
    wscript.echo _
           "Syntax: search filename | filename.* | *.extension [-q] [> outputfile]"
    wscript.quit
  elseif wscript.arguments(0) = "?" then 
    wscript.echo _
           "Syntax: search filename | filename.* | *.extension [-q] [> outputfile]"
    wscript.quit
  end if

elseif wscript.arguments.count = 2 then
  if Lcase(wscript.arguments(1)) <> "-q" then
    wscript.echo _
        "Syntax: search filename | filename.* | *.extension [-q] [> outputfile]"
    wscript.quit
  else
    blnQuiet = True
  end if
end if

strTarget = wscript.arguments(0)

if right(strTarget,1) = "*" then
  strKey = "System.FileName"
  strTarget = left(strTarget,len(strTarget)-2)

elseif left(strTarget,1) = "*" then 
  strKey = "System.FileExtension"
  strTarget = right(strTarget,len(strTarget)-1)

else
  strKey = "System.ParsingName"
end if

iStart = Timer

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet  = CreateObject("ADODB.Recordset")
Set objCommand    = CreateObject("ADODB.Command")

objConnection.Open _
  "Provider=Search.CollatorDSO;Extended properties='Application=Windows';"
objCommand.ActiveConnection = objConnection

objRecordSet.Open "SELECT System.ItemPathDisplay, System.Size FROM SYSTEMINDEX" _
  & " where " & strKey & " = '" & strTarget &"' order by System.Filename", objConnection
objRecordSet.MoveFirst

Do Until objRecordset.EOF
  If objRecordSet.EOF Then
    wscript.echo "No such file found"
    wscript.quit 0
  else
    intSize = objRecordset.Fields.Item("System.Size")
    if not blnQuiet then
      if intSize <> "" then
        Wscript.Echo _
               objRecordset.Fields.Item("System.ItemPathDisplay")
      else
        Wscript.Echo _
               objRecordset.Fields.Item("System.ItemPathDisplay") & " [folder]"
      end if
    end if
  intNbFiles = intNbFiles + 1
  objRecordset.MoveNext
  end if
Loop

iStop = Timer

wscript.echo vbcrlf & intNbFiles & " files found in " & (iStop - iStart) & " seconds among " &_
                                   GetNrOfIndexedFiles() & " entries in index."
wscript.quit 0

'-----------------------------------------------------------------------------------
Function GetNrOfIndexedFiles()

Dim intNrOfFiles, strComputer, objWMIService, colItems, objItem

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set colItems = objWMIService.ExecQuery( _
    "SELECT * FROM Win32_PerfRawData_WSearchIdxPi_SearchIndexer",,48) 

For Each objItem in colItems 
    intNrOfFiles = objItem.DocumentsFiltered
Next

GetNrOfIndexedFiles = intNrOfFiles

end function