1

Тема: WSH: Поиск файлов на компьютерах по сети WMI

Доброе время суток!

Столкнулся с необходимостью поиска фалов на компьютерах сети по маске (например, qwe*.*). На форуме нашел реализацию асинхронного поиска с помощью WMI http://forum.script-coding.com/viewtopic.php?id=3783
Пытаюсь переделать под свои нужды не получается в части формирования запроса.


Option Explicit

Dim arrComputers()
Dim strComputer

Dim objSWbemServicesEx
Dim objSWbemSink
Dim objSWbemNamedValueSet

Dim lngCount, i

Dim objFSO, objFile

On Error Resume Next

' Массив адресов/имён опрашиваемых машин
' В принципе, можно получать из сетевого окружения, с контроллера домена
' или перебором доступных адресов подсети
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("computers.txt", 1)
Const DATA_DIR ="files\"
Const DATA_EXT = ".txt"
Const strDrive = "c:"
Const strPath = "\" 'целевой каталог
Const strExtension = "txt"

i=0
' reading lines from file
Do Until objFile.AtEndOfStream
    Redim Preserve arrComputers(i)
    arrComputers(i) = objFile.ReadLine
    i = i + 1
Loop

objFile.Close

lngCount     = UBound(arrComputers) + 1

Set objSWbemServicesEx = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\Root\CIMV2")
Set objSWbemSink       = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")

For Each strComputer In arrComputers

    ' В коллекции «objSWbemNamedValueSet» будем передавать адрес/имя хоста (замечание: в данном конкретном случае
    ' сие, в принципе, необязательно, поскольку класс Win32_PingStatus и так содержит
    ' свойство «.Address», но тут показана сама технология передачи данных в процедуру асинхронной обработки)
    Set objSWbemNamedValueSet = WScript.CreateObject("WbemScripting.SWbemNamedValueSet")
    objSWbemNamedValueSet.Add "HostName", strComputer
    
    ' Все запросы будут обрабатываться в единственной процедуре обработки
'    objSWbemServicesEx.ExecQueryAsync objSWbemSink, "SELECT * FROM Win32_PingStatus WHERE ADDRESS = '" & strComputer & "'", , , , objSWbemNamedValueSet
    objSWbemServicesEx.ExecQueryAsync objSWbemSink, "SELECT * FROM CIM_DataFile WHERE Drive = '" & strDrive & "' AND Path = '\\" & Replace(strPath,"\","\\") & "\\' AND FileName Like 'qwe%' AND Extension = '" & strExtension & "'", , , , objSWbemNamedValueSet
    
Next

' Ожидаем, пока не будут обработаны все асинхронные запросы
Do
    WScript.Sleep 100
Loop Until lngCount = 0

objSWbemSink.Cancel

Set objSWbemSink       = Nothing
Set objSWbemServicesEx = Nothing

WScript.Quit 0
'=============================================================================

'=============================================================================
' Процедура асинхронной обработки экземпляра объекта (замечание: в данном конкретном случае
' будет возвращаться единственный объект, однако, в большинстве случаев запросы
' возвращают множество объектов)
Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext)
    Dim strComputer
    strComputer = objWbemAsyncContext.Item("HostName")    

    Dim fso, tf_ip, objFile, i
    Set fso = CreateObject("Scripting.FileSystemObject")    
    Set tf_ip = fso.CreateTextFile(DATA_DIR & strComputer & DATA_EXT, True)    
    Set objFile = CreateObject("WScript.Shell")

i = 0 'счетчик

If objWbemObject.Count > 0 Then 'если файлы найдены    
    For Each objFile In objFiles
        'пишем имя файла в лог
        tf_ip.Write(objFile.Name)
        i = i + 1
    Next
End If
    tf_ip.Close
End Sub
'=============================================================================

'=============================================================================
' Процедура, вызываемая при завершении асинхронной обработки
Sub Sink_OnCompleted(iHResult, objWbemErrorObject, objWbemAsyncContext)
    objWbemAsyncContext.DeleteAll
    Set objWbemAsyncContext = Nothing
    
    ' Уменьшаем счётчик оставшегося числа асинхронных обработок
    lngCount = lngCount - 1
End Sub
'=============================================================================

2 (изменено: Rom5, 2014-08-19 16:05:56)

Re: WSH: Поиск файлов на компьютерах по сети WMI

Если ещё актуально, то пробуйте добавить символ "%" и в начало like-выражения:

...
AND FileName Like 'qwe%'
...

вот, так:


AND FileName Like '%qwe%'

ps. только, по моему мнению, в Вашем скрипте идет поиск файлов не на удалённых машинах, а только лишь на своей локальной (wmi-подключение и асинхронный запрос - только к ней), а соответственно и лог-файлы создадуться сдублированные, ещё и запись в них без учёта возможной "дозаписи" свеженыйденных файлов на машине.

В общем, если задача ещё нужна, то маякуйте - доведём до ума.

WBR. Roman

3

Re: WSH: Поиск файлов на компьютерах по сети WMI

Добрый день!

Задача еще нужна.

AND FileName Like '%qwe%'

так не получилось.

в Вашем скрипте идет поиск файлов не на удалённых машинах

Почему? Я вместо того что бы указывать ip адреса компьютеров ручками сделал загружать из файла

Dim lngCount, i

Dim objFSO, objFile

On Error Resume Next

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("computers.txt", 1)


'ТУТ ЗАГРУЖАЕМ ПИСОК КОМПЬЮТЕРОВ ИЗ ФАЙЛА computers.txt
i=0
' reading lines from file
Do Until objFile.AtEndOfStream
    Redim Preserve arrComputers(i)
    arrComputers(i) = objFile.ReadLine
    i = i + 1
Loop

objFile.Close

lngCount     = UBound(arrComputers) + 1

Set objSWbemServicesEx = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\Root\CIMV2")
Set objSWbemSink       = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")

For Each strComputer In arrComputers