Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Помогите наваять скрипт? Поиск строки в файле. (http://forum.oszone.net/showthread.php?t=324452)

glukin 04-03-2017 12:37 2716598

Помогите наваять скрипт? Поиск строки в файле.
 
Есть файл dns.txt вида

c1601.f1_r1_1.m IN A 10.30.4.61
c1601.f1_r1_1_s1.m IN A 10.30.4.61
c1601.kf1_r1_1_s0.m IN A 10.30.4.78
c2811.f1-r1_1.m IN A 10.30.40.1
c2811.f1-r1_1_vl2.m IN A 10.30.40.1
c2811.f1-r1_1_s0-0-0_1.m IN A 10.30.40.10
c7206.f2-r206_1_vl15.m IN A 10.30.40.101
zy782.hd_f2-r1_1_dsl.m IN A 10.30.40.102
zy791.h3_f1-r1_1.m IN A 10.30.40.105
zy791.h3_f1-r1_1_lan.m IN A 10.30.40.105

порядка 6000 строк.
Нужно в нем в цикле смотреть строку 10.30.0-255.0-255 и если ее нет, то добавлять в конец файла сформированную строку "ИмяУстройства IN A ИПАдрес", строку я знаю как формировать. Прошу помощи. И еще самый главный вопрос - когда я формирую это файл - он генерится около 12 часов (пинг по IP с таймаутом 1 сек, если есть пинг, то опрос по SNMP), так вот - не увеличит ли поиск такого каждого IP в этом файле время работы скрипта в геометрической прогрессии? Сумбурно написал...

Iska 04-03-2017 14:43 2716614

Цитата:

Цитата glukin
Есть файл dns.txt вида »

Упакуйте его в архив и приложите к сообщению.

Цитата:

Цитата glukin
в цикле »

Это как?

Цитата:

Цитата glukin
смотреть строку 10.30.0-255.0-255 »

Не вижу в Вашем примере даже относительно похожей строки. Или Вы в «10.30.0-255.0-255» что-то хитро зашифровали, что б не догадались?

Цитата:

Цитата glukin
то добавлять в конец файла сформированную строку "ИмяУстройства IN A ИПАдрес", строку я знаю как формировать. »

То есть, реальное содержимое «ИмяУстройства IN A ИПАдрес» — лежит на Вас?

Цитата:

Цитата glukin
когда я формирую это файл - он генерится около 12 часов (пинг по IP с таймаутом 1 сек, если есть пинг, то опрос по SNMP), »

Вы не думали делать хотя бы пинг не последовательно?

Цитата:

Цитата glukin
так вот - не увеличит ли поиск такого каждого IP в этом файле время работы скрипта в геометрической прогрессии? »

Вы хотите, чтобы скрипт а) читал из файла и б) писал в файл в то время, когда Вы пишете в тот же самый файл из другого приложения? Коллизии могут быть (либо наверняка будут, зависит от того, как именно пишете).

Цитата:

Цитата glukin
Сумбурно написал... »

Ото ж.

megaloman 04-03-2017 17:46 2716649

glukin, Сумбурно написал... таки да! Опрашивайте Вашу сеть, пишите результаты в новый файл, например, dns.txt.tmp, после завершения опроса запустите процесс анализа dns.txt на основе dns.txt.tmp, делая необходимые дополнения. А затем я бы еще отсортировал dns.tmp например по IP. Порядок освобождает мысль.
Или, еще лучше, прежде чем пинговать, поищите IP в dns.tmp, и, если он есть, не пингуйте - Вы уже это ранее сделали, зачем делать заново? А то , что пропингуете, запишите в dns.txt.tmp и по окончании, объедините инфу из обоих файлов.

glukin 04-03-2017 18:51 2716673

Вложений: 1
Iska,
1. Файл вложил, пароль в личке. PS^ Вам не отправляется личка, пишет: Iska превысил(а) максимальный объем сохраненных персональных сообщений и не может получать новые сообщения, пока не удалит часть старых.
2. Напишу как умею - на С:
for(i=0;i<256;i++)
for(j=0;j<256;j++)
{Тело цикла;}
3. Строка - IP-адрес, формируемый из 10.30 + i + j.
4. Да.
5. Не последовательно - это как? Мне нужно, чтобы весь диапазон был опрошен.
6. Необязательно, можно те IP, которых нет, добавить в отдельный файл, потом этот файл соединить с исходным.

glukin 04-03-2017 18:55 2716676

Цитата:

Цитата megaloman
после завершения опроса запустите процесс анализа dns.txt на основе dns.txt.tmp »

Как??
Думаю, может, сделать по-другому?
Я 1 раз сформирую эталонный файл dns.txt, затем по расписанию пинговать всю сеть на предмет появления новых устройств, формировать новый файл dns.txt.tmp и сравнивать 2 файла. Разницу в файлах дописывать в конец эталона, вот так вроде правильно написал.

"А затем я бы еще отсортировал dns.tmp например по IP."
Они и так будут по IP, dns.tmp пишется в цикле же i=0-255;j=0-255.

А можно как-либо сравнить 2 файла, чтобы выделить неприсутствующие во втором файле строки в отдельный файл (с ними потом еще работать другому скрипту) и дописать их в первый файл?

glukin 04-03-2017 19:20 2716690

Вероятно, задача нерешаема без административных методов. Не могу сообразить, что делать, если устройство выведено из эксплуатации и не пингуется, но в эталонном dns.txt оно есть. И еще - их периодически выключают, то есть они могут быть в эксплуатации, но не пинговаться. (((

megaloman 04-03-2017 22:34 2716742

glukin, чтобы выделить не присутствующие во втором файле строки в отдельный файл надо сформировать IP-адрес, поискать его в dns.txt, если его нет - пингуем и пишем в файл dns.txt.tmp - я эту идею уже излагал.

Если устройство выведено из эксплуатации и не пингуется, удалить его из эталонного файла можно только ручками, так как имеются другие устройства в эксплуатации, но не пингуются, так как выключены.

Можно, конечно, перепинговать все имеющиеся в dns.txt устройства, имеющиеся непингуемые записать в отдельный файл, затем опять же глазками его проанализировать.
Наверное, стоит разделить эти задачи: поиск новых и анализ непингуемых.

Вероятно, задача нерешаема без административных методов - на каждый объект должен быть паспорт, нас по требованиям безопасности заставили это сделать. Там отображаются все изменения объекта, от ввода в эксплуатацию, изменения конфигурации и софта, до его утилизации.

А сортировать данные после объединения 2 файлов всё равно придётся, так как Вы собираетесь добавлять в конец файла новые сформированные строки, которые уже выпадают из предыдущего порядка следования.

А для меня пароль недоступен? Боитесь, что контрагайку откручу? :)

glukin 05-03-2017 10:36 2716820

1. Это сделать я могу.
2. Так я и затеял все это, чтобы не делать ручками. Устройства выключают только на ночь и на выходные, так что можно успеть, но проблема в том, что скрипт работает очень долго (порядка 15 часов), можно и не успеть. А с учетом анализа dns.txt боюсь, что время увеличится в разы.
3. Да, пожалуй.
4. Это все есть, но неудобно, слишком все распределено территориально и слишком много админов.
5. А для чего вообще его сортировать?
6. Пароль выслал.

Iska 05-03-2017 10:57 2716826

glukin, к сожалению, цели и задачи я не смог уяснить толком. Посему, могу лишь дать наводку на улучшение той части, которую понял.

Асинхронные запросы Wbem: vbscript: асинхронная обработка множественных запросов WMI — Windows Script Host, HTA (VBScript, JScript) — Коллекция скриптов и идей — Серый форум.
Фоновые задания PowerShell, используемый класс .Net — System.Net.NetworkInformation.Ping: Многопоточный сканер сети | PowerShell и другие скрипты (даю ссылку на кэш Google'а, поскольку сайт Василия, видимо, того… Увы :().

Вы, поскольку знаете C/C++, кроме изложенного выше, можете и вовсе банально использовать в своём приложении несколько потоков. Кроме того, Вы можете писать не в текстовый файл, а в базу данных — Jet или SQL (если есть), в последующем работать с базой данных будет многим проще (фильтрация, запросы и т.п.), нежели с банальным текстовым файлом. В частности, задача:
Цитата:

Цитата glukin
А можно как-либо сравнить 2 файла, чтобы выделить неприсутствующие во втором файле строки в отдельный файл (с ними потом еще работать другому скрипту) и дописать их в первый файл? »

для двух таблиц базы данных решается одним запросом ;).

glukin 05-03-2017 11:16 2716831

Цель - актуализировать прямую и обратную зоны DNS для DNS-сервера устройств СПД, так, чтобы там не было выведенных из эксплуатации устройств, и , наоборот, не вводить вновь введенные в эксплуатацию устройства туда руками, как это делается сейчас.

"Асинхронные запросы Wbem"
О! Вот это полезная штука, спасибо большое! Потестю на предмет скорости, если будет быстрее хотя бы раза в 2, чем сейчас - решится проблема выключенных устройств, находящихся в эксплуатации.
PowerShell не подходит, так как сервер, где будет работать скрипт - Win2003, и переехать на другой нет возможности, так как только с него разрешен SNMP на устройства СПД.

Я понимаю, что с БД будет работать быстрее, и , возможно, проще, но БД я не умею от слова "вообще".

Iska 05-03-2017 11:40 2716836

Цитата:

Цитата glukin
"Асинхронные запросы Wbem"
О! Вот это полезная штука, спасибо большое! Потестю на предмет скорости, если будет быстрее хотя бы раза в 2, чем сейчас »

Будет, коллега, будет. И куда быстрее, чем в два раза ;). Посмотрите тогда ещё и само обсуждение вот в этой теме: VBScript / WMI : Асинхронный мультипинг — Windows Script Host, HTA (VBScript, JScript) — Общение — Серый форум (именно из неё выросла тема в Коллекции). Там есть и временные оценки, и ещё кое-что, что может быть для Вас интересным.

Цитата:

Цитата glukin
PowerShell не подходит, так как сервер, где будет работать скрипт - Win2003, и переехать на другой нет возможности, »

PowerShell второй версии есть и для Windows Server 2003. BITS 4.0 будет, конечно, недоступен, но остальное — вполне:
Windows Management Framework (Windows PowerShell 2.0, WinRM 2.0, and BITS 4.0)
Download Update for Windows Server 2003 (KB968930) from Official Microsoft Download Center

Цитата:

Цитата glukin
Я понимаю, что с БД будет работать быстрее, и , возможно, проще, но БД я не умею от слова "вообще". »

Ну, ключевые слова — ADODB, Recordset, Connection. В принципе, там нет ничего сложного.

glukin 05-03-2017 12:26 2716854

Спасибо! Пока попробую асинхронный опрос, по результату отпишусь.

glukin 05-03-2017 12:44 2716863

del

glukin 06-03-2017 15:37 2717207

Iska, Все отлично! Прирост в скорости примерно в 20 раз. То, что нужно!!
Проблема обнаружилась другая - почему-то не все устройства отдают свой SNMP sysName при абсолютно одинаковых настройках, но это вопрос, наверное, не сюда.
Буду допиливать дальше...

glukin 07-03-2017 13:02 2717383

Поясните, пожалуйста, почему не работает конструкция вида:

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

strComputer = objWbemAsyncContext.Item("HostName")

If Not IsNull(objWbemObject.StatusCode) Then
If objWbemObject.StatusCode = 0 Then

objWmiNamedValueSet.Add "AgentAddress", strComputer
objWmiNamedValueSet.Add "AgentReadCommunityName", "poll"
'on error resume next
Set colSystem = objWmiServices.InstancesOf("SNMP_RFC1213_MIB_system", , objWmiNamedValueSet)
WSCript.Echo IsNull(objSystem)
If Not IsNull(colSystem) Then
For Each objSystem In colSystem
If (Right(objSystem.sysName,12)="123") Then
objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m"
Else
objSystem.sysName=objSystem.sysName + ".m"
End If
NFile1.WriteLine objSystem.sysName + " IN A " + strComputer
Next
Else
objWmiNamedValueSet.Add "AgentReadCommunityName", "public"
Set colSystem = objWmiServices.InstancesOf("SNMP_RFC1213_MIB_system", , objWmiNamedValueSet)
If Not IsNull(colSystem) Then
For Each objSystem In colSystem
If (Right(objSystem.sysName,12)="123") Then
objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m"
Else
objSystem.sysName=objSystem.sysName + ".m"
End If
NFile1.WriteLine objSystem.sysName + " IN A " + strComputer
Next
Else

NoSNMP.WriteLine strComputer

End If
End If

End If
End If
End Sub

Выдаёт ошибку null на "For Each objSystem In colSystem"

Iska 07-03-2017 13:09 2717386

glukin, используйте тэг code для оформления кода.

Цитата:

Цитата glukin
почему не работает конструкция вида: … Выдаёт ошибку null на "For Each objSystem In colSystem" »

Проверяйте так:
Код:

If Not colSystem Is Nothing Then

glukin 07-03-2017 13:37 2717393

Iska, Без изменений.
ПС: на устройствах, которые отдают SNMP sysName все работает, не работает только на тех, которые SNMP не умеют.

Iska 07-03-2017 14:12 2717400

Тогда детализируйте (ибо гадать не интересно) — на каком из двух:
Цитата:

Цитата glukin
For Each objSystem In colSystem»

происходит ошибка? Приведите точное сообщение об ошибке (можно просто нажать Ctrl-C в окне сообщения.

glukin 07-03-2017 14:20 2717403

Iska, На первом.
---------------------------
Windows Script Host
---------------------------
Script: C:\Documents and Settings\Administrator\Desktop\ping.vbs
Line: 117
Char: 5
Error: 0x80041010
Code: 80041010
Source: (null)

---------------------------
OK
---------------------------
ПС: Я понимаю, что при скане ИП-адресов какой-то из ИП выдает NULL, то есть или не умеет SNMP, или access denied, но почему этот NULL не обрабатывается If'ами?

Iska 07-03-2017 15:07 2717411

Ну, это ведь совсем не «null». Судя по описанию, Вы пытаетесь использовать несуществующий класс в указанном пространстве Wbem.

Попробуйте сделать проверку существования класса, наподобие:
Код:

Option Explicit

Dim strComputer

Dim objSWbemLocator
Dim objSWbemServicesEx
Dim collSWbemObjectSet
Dim objSWbemObjectEx


strComputer = "."

Set objSWbemLocator    = WScript.CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServicesEx = objSWbemLocator.ConnectServer(strComputer, "root\cimv2")

WScript.Echo ClassExists(objSWbemServicesEx, "bla-bla-bla")
WScript.Echo ClassExists(objSWbemServicesEx, "Win32_Process")
WScript.Echo ClassExists(objSWbemServicesEx, "CIM_OperatingSystem")
WScript.Echo ClassExists(objSWbemServicesEx, "SNMP_RFC1213_MIB_system")


If ClassExists(objSWbemServicesEx, "SNMP_RFC1213_MIB_system") Then
        Set collSWbemObjectSet = objSWbemServicesEx.InstancesOf("SNMP_RFC1213_MIB_system")
       
        For Each objSWbemObjectEx In collSWbemObjectSet
                '…
        Next
Else
        ' …
End If

WScript.Quit 0


Function ClassExists(objSWbemServicesEx, strClassName)
        Dim objSWbemObjectEx
       
        ClassExists = False
       
        For Each objSWbemObjectEx In objSWbemServicesEx.SubclassesOf()
                If StrComp(objSWbemObjectEx.Path_.RelPath, strClassName, vbTextCompare) = 0 Then
                        ClassExists = True
                       
                        Exit Function
                End If
        Next
End Function


glukin 07-03-2017 20:37 2717489

Iska, Боюсь, что для меня это крутовато, не осилил. Пожалуй сделаю как-то так:
on error resume next
затем если (пинг прошел)&(была запись в файл) то NoSNMP=False
иначе NoSnmp=True
если NoSNMP то пишем в файл ИП-адрес "плохого" устройства

Только пока не разобрался с переходами по on error resume next

Трудно без нормального отладчика с контрольными точками и пошаговым выполнением команд (((


Покритикуйте алгоритм.

glukin 09-03-2017 12:29 2717846

Прошу помощи в реализации на vbs.

Iska 09-03-2017 12:47 2717854

Покажите Ваш текущий код (не забывайте обрамлять его тэгом «code»).

glukin 09-03-2017 13:10 2717862

Iska, Вот
Код:

'=============================================================================
' Процедура асинхронной обработки экземпляра объекта (замечание: в данном конкретном случае
' будет возвращаться единственный объект, однако, в большинстве случаев запросы
' возвращают множество объектов)
Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext)
    Dim strComputer   
    strComputer = objWbemAsyncContext.Item("HostName")   
    If Not IsNull(objWbemObject.StatusCode) Then
    If objWbemObject.StatusCode = 0 Then
      objWmiNamedValueSet.Add "AgentAddress", strComputer
      objWmiNamedValueSet.Add "AgentReadCommunityName", "poll"
      on error resume next
   
Set colSystem = objWmiServices.InstancesOf("SNMP_RFC1213_MIB_system", , objWmiNamedValueSet)
      For Each objSystem In colSystem
'На предыдущей строке  выдает error, если устройство не умеет SNMP.
      If (Right(objSystem.sysName,12)="123456789012") Then             
        objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m"
      Else 
        objSystem.sysName=objSystem.sysName + ".m"             
        End If
      NFile1.WriteLine objSystem.sysName + "        IN        A        " + strComputer 
      Next
    End If
    End If
End Sub

Нужно - если устройство не умеет SNMP, то записать его ИП-адрес в файл.
Другими словами - прошел пинг и прошла запись
"NFile1.WriteLine objSystem.sysName + " IN A " + strComputer"
то оно умеет, иначе пишем его ИП-адрес в файл для дальнейшего анализа.

Iska 09-03-2017 13:25 2717870

glukin, это только одна процедура. Я имел в виду — весь код.

glukin 09-03-2017 13:30 2717875

Iska, ок
Код:

File_Out1 = "D:\SNMP.txt"
File_Out2 = "D:\30.10.txt"
File_out3 = "D:\31.10.txt"
File_Date = "D:\date.txt"
File_NoSNMP = "D:\NoSNMP.txt"

Set objWmiLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWmiServices = objWmiLocator.ConnectServer("", "root\snmp\localhost")
Set objWmiNamedValueSet = CreateObject("WbemScripting.SWbemNamedValueSet")

Set FSO = CreateObject("Scripting.FileSystemObject")


Set NFile1 = FSO.OpenTextFile(File_Out1, 2, True)
Set NFile2 = FSO.OpenTextFile(File_Out2, 2, True)
Set NFile3 = FSO.OpenTextFile(File_Out3, 2, True) 
Set DateFile = FSO.OpenTextFile(File_Date, 2, True)
Set NoSNMP = FSO.OpenTextFile(File_NoSNMP, 2, True) 







'Option Explicit

Dim arrComputers(255)
k = 0
For i = 115 To 115
 For j = 0 To 255
  arrComputers(k) = "10.31." + CStr(i) + "." + CStr(j)
  k = k + 1
 Next
Next




Dim strComputer

Dim objSWbemServicesEx
Dim objSWbemSink
Dim objSWbemNamedValueSet

Dim lngCount
Dim lngQueueCurrLength, lngQueueMaxLength
Dim i



' Максимальная длина очереди (в данном примере — сколько машин будут пинговаться одновременно),
' выбирается произвольно
lngQueueMaxLength  = 10
' Текущая длина очереди
lngQueueCurrLength = 0

lngCount = UBound(arrComputers)
i = 0

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

While (i <= lngCount) Or (lngQueueCurrLength > 0) ' Пингуем пока не кончатся компы и очередь
    If (i <= lngCount) And (lngQueueCurrLength < lngQueueMaxLength) Then
       
        ' В коллекции «objSWbemNamedValueSet» будем передавать адрес/имя хоста (замечание: в данном конкретном случае
        ' сие, в принципе, необязательно, поскольку класс Win32_PingStatus и так содержит
        ' свойство «.Address», но тут показана сама технология передачи данных в процедуру асинхронной обработки)
        Set objSWbemNamedValueSet = WScript.CreateObject("WbemScripting.SWbemNamedValueSet")
        objSWbemNamedValueSet.Add "HostName", arrComputers(i)
       
        ' Все запросы будут обрабатываться в единственной процедуре обработки
        objSWbemServicesEx.ExecQueryAsync objSWbemSink, "SELECT * FROM Win32_PingStatus WHERE ADDRESS = '" & arrComputers(i) & "'", , , , objSWbemNamedValueSet
       
        i = i + 1
        lngQueueCurrLength = lngQueueCurrLength + 1
    Else
        ' Ожидаем, пока не будут обработаны все асинхронные запросы
        WScript.Sleep 100
    End If
Wend

objSWbemSink.Cancel

Set objSWbemSink      = Nothing
Set objSWbemServicesEx = Nothing
NFile1.Close
NFile2.Close
NFile3.Close
NoSNMP.Close
DateFile.Close

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

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

objWmiNamedValueSet.Add "AgentAddress", strComputer
    objWmiNamedValueSet.Add "AgentReadCommunityName", "poll"
on error resume next
    Set colSystem = objWmiServices.InstancesOf("SNMP_RFC1213_MIB_system", , objWmiNamedValueSet)


    For Each objSystem In colSystem

        If (Right(objSystem.sysName,12)=".123456789012") Then             
              objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m"
        Else 
              objSystem.sysName=objSystem.sysName + ".m"             
        End If
        NFile1.WriteLine objSystem.sysName + "        IN        A        " + strComputer 
    Next

     
  End If
  End If
End Sub
'=============================================================================

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


Iska 09-03-2017 14:21 2717887

Тяжёлый код. Используйте Option Explicit в начале кода, препятствует появлению многих глупых ошибок с описками в именовании переменных.

Попробуйте так (добавить всё ту же функцию):
Код:

Function ClassExists(objSWbemServicesEx, strClassName)
        Dim objSWbemObjectEx
       
        ClassExists = False
       
        For Each objSWbemObjectEx In objSWbemServicesEx.SubclassesOf()
                If StrComp(objSWbemObjectEx.Path_.RelPath, strClassName, vbTextCompare) = 0 Then
                        ClassExists = True
                       
                        Exit Function
                End If
        Next
End Function

Код:

Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext)
        Dim strComputer
       
        strComputer = objWbemAsyncContext.Item("HostName")
       
        If Not IsNull(objWbemObject.StatusCode) Then
                If objWbemObject.StatusCode = 0 Then
                       
                       
                        objWmiNamedValueSet.Add "AgentAddress", strComputer
                        objWmiNamedValueSet.Add "AgentReadCommunityName", "poll"
                        'On Error Resume Next
                       
                        If ClassExists(objWmiServices, "SNMP_RFC1213_MIB_system") Then
                                Set colSystem = objWmiServices.InstancesOf("SNMP_RFC1213_MIB_system", , objWmiNamedValueSet)
                               
                               
                                For Each objSystem In colSystem
                                       
                                        If (Right(objSystem.sysName,12)=".123456789012") Then             
                                                objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m"
                                        Else 
                                                objSystem.sysName=objSystem.sysName + ".m"             
                                        End If
                                        NFile1.WriteLine objSystem.sysName + "        IN        A        " + strComputer 
                                Next
                        Else
                                ' Здесь добавляете код для «прошёл пинг, но нет указанного класса».
                        End If

                Else
                        ' Здесь добавляете код для «пинг не прошёл».

                End If
        Else
                ' Здесь добавляете код для «пинг не прошёл».

        End If
End Sub


glukin 09-03-2017 18:32 2717961

Iska, ОК, спасиб, завтра буду пробовать.
А еще, не подскажете, как мне из строки вида "10.31.101.102" сформировать строку вида "102.101" в этой же функции после строки
"NFile1.WriteLine objSystem.sysName + " IN A " + strComputer "
?
Ну то есть, брать 2 последних октета из strComputer и их поменять местами? А то как не пробую - у меня все type mismatch вылезает.
Да, я понял, что так писать нельзя (без обявления переменных), но с нуля сложно пока для меня за всеми переменными уследить, да еще и без отладчика, в блокноте. (((

Iska 09-03-2017 18:58 2717972

Цитата:

Цитата glukin
Ну то есть, брать 2 последних октета из strComputer и их поменять местами? »

Проще всего — разбить строку на массив октетов и взять два последних из четырёх, поменяв их местами.
Быстро
Код:

WScript.Echo Split("10.31.101.102", ".")(3) & "." & Split("10.31.101.102", ".")(2)

По-научному
Код:

Option Explicit

Dim strValue
Dim arrValues


strValue = "10.31.101.102"
arrValues = Split(strValue, ".")

WScript.Echo arrValues(3) & "." & arrValues(2)

WScript.Quit 0



Цитата:

Цитата glukin
Да, я понял, что так писать нельзя (без обявления переменных),»

Писать можно, но отслеживание в этом случае возможных описок весьма тяжело даётся.

Цитата:

Цитата glukin
но с нуля сложно пока для меня за всеми переменными уследить, да еще и без отладчика, в блокноте. ((( »

Консоль наше всё :):
Скрытый текст

Скрытый текст

Я ж Вам писал:
Цитата:

Цитата Iska
glukin, редактор Far Manager'а, SciTE. VBSEdit также весьма хорош (но не бесплатен). »


glukin 09-03-2017 19:18 2717977

Iska, Я так понимаю, что это будет работать, только если "101.102", а если "1.2"? То есть октеты не обязательно будут в 3 символа.
В Фаре не нашел такой функциональности, VBSEdit хорош, но пошаговой отладки тоже там не нашел.
Да и платить не хочется. )))

Iska 09-03-2017 20:03 2717985

Цитата:

Цитата glukin
Iska, Я так понимаю, что это будет работать, только если "101.102", а если "1.2"? То есть октеты не обязательно будут в 3 символа. »

Будет работать. Функция Split() разбивает строку в массив на составляющие по разделителю, в данном случае — по точке.

Цитата:

Цитата glukin
В Фаре не нашел такой функциональности, »

Я пришёл к выводу, что лучшая отладка — консоль и WScript.Echo.

Цитата:

Цитата glukin
VBSEdit хорош, но пошаговой отладки тоже там не нашел. »

Скрытый текст


В принципе, можно пользовать Microsoft Script Debugger. При наличии Microsoft Office, использовать тамошний отладчик из редактора Microsoft Script Editor, но, повторюсь: для меня самый быстрый способ — редактор и консоль Far Manager'а.

glukin 14-03-2017 16:57 2719414

Iska, добрый день, наконец-то у меня дошли руки до скрипта.
Вы писали: "Попробуйте так (добавить всё ту же функцию):"
Все равно не работает, выдает ошибку, когда натыкается на устройство без SNMP - тот же (null)
---------------------------
Windows Script Host
---------------------------
Script: C:\Documents and Settings\rp\Desktop\ping1.vbs
Line: 120
Char: 12
Error: 0x80041010
Code: 80041010
Source: (null)

---------------------------
OK
---------------------------
Вот код процедуры, что я делаю не так?
Код:

Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext)
    Dim strComputer
   
    strComputer = objWbemAsyncContext.Item("HostName")
   
    If Not IsNull(objWbemObject.StatusCode) Then
        If objWbemObject.StatusCode = 0 Then
           

          objWmiNamedValueSet.Add "AgentAddress", strComputer
          objWmiNamedValueSet.Add "AgentReadCommunityName", "poll"
'on error resume next



          If ClassExists(objWmiServices, "SNMP_RFC1213_MIB_system") Then
          Set colSystem = objWmiServices.InstancesOf("SNMP_RFC1213_MIB_system", , objWmiNamedValueSet)


          For Each objSystem In colSystem

            If (Right(objSystem.sysName,12)=".123456789012") Then             
              objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m"
            Else 
              objSystem.sysName=objSystem.sysName + ".m"             
            End If
            NFile1.WriteLine objSystem.sysName + "        IN        A        " + strComputer 
          Next
          Else
            WScript.Echo "OK"
            NoSNMP.WriteLine strComputer
          End If
 

  End If
  End If
End Sub

Line 120, на которую ругается, выделена жирным.
Спасибо.

Добавил отладки, в жирную ветку функции, которую Вы посоветовали, не попадает. ((
Код:

Function ClassExists(objSWbemServicesEx, strClassName)
        Dim objSWbemObjectEx
       
        ClassExists = False
       
        For Each objSWbemObjectEx In objSWbemServicesEx.SubclassesOf()
                If StrComp(objSWbemObjectEx.Path_.RelPath, strClassName, vbTextCompare) = 0 Then
                        ClassExists = True
                        WScript.Echo "GOOD"
                       
                        Exit Function
                End If
        Next
      WScript.Echo "BAD"
End Function


Iska 14-03-2017 18:53 2719455

glukin, такое ощущение, что класс есть, а экземпляров класса нет. Попробуйте всё-таки вместо прямого обращения к коллекции по .InstancesOf("SNMP_RFC1213_MIB_system"…) сделать запрос посредством .ExecQuery("SELECT * FROM SNMP_RFC1213_MIB_system"…).

Мне, к сожалению, банально даже не на чем проверить.

glukin 14-03-2017 21:25 2719519

Iska, Ничего не понимаю.
Попробовал дома на устройствах, которые точно не умеют SNMP - все работает!
Дома Win7 Ultimate, где ошибка - Win2003, может, дело в версиях винды и 2003-я винда не умеет, то что Вы написали?
Только проблема в том, что дома наоборот - нет того, кто бы умел SNMP, полностью работу не проверишь. ))

glukin 15-03-2017 09:38 2719629

Iska, Добавлю: убрал проверку на ClassExists, ошибка вылетает такая же, то есть в Win2003 не работает функция ClassExists, а в Win7 она работает.
Проверить можно на локалхосте (127.0.0.0-255).
Help!

glukin 15-03-2017 21:21 2719798

Iska, "glukin, такое ощущение, что класс есть, а экземпляров класса нет. Попробуйте всё-таки вместо прямого обращения к коллекции по .InstancesOf("SNMP_RFC1213_MIB_system"…) сделать запрос посредством .ExecQuery("SELECT * FROM SNMP_RFC1213_MIB_system"…)."

Все то же самое...
---------------------------
Windows Script Host
---------------------------
Script: C:\Documents and Settings\rp\Desktop\ping1.vbs
Line: 121
Char: 12
Error: 0x80041010
Code: 80041010
Source: (null)

---------------------------
OK
---------------------------
На той же строке.

Iska 16-03-2017 08:42 2719879

glukin, что мне потребуется для того, чтобы проверить у себя работу Вашего скрипта?

glukin 16-03-2017 09:26 2719885

Iska, сделал через If Error Resume Next, так что думаю на этом и остановиться.
Спасибо.

glukin 16-03-2017 11:24 2719920

Iska, впрочем, если есть желание и время, можете попробовать, вот код для локалхоста, но нужен или win2003 server или winXP. Ибо на 7-ке все работает.
Скрытый текст
Код:

File_Out1 = "C:\SNMP.txt"
File_Out2 = "C:\30.10.txt"
File_out3 = "C:\31.10.txt"
File_Date = "C:\date.txt"
File_NoSNMP = "C:\NoSNMP.txt"

Set objWmiLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWmiServices = objWmiLocator.ConnectServer("", "root\snmp\localhost")
Set objWmiNamedValueSet = CreateObject("WbemScripting.SWbemNamedValueSet")

Set FSO = CreateObject("Scripting.FileSystemObject")


Set NFile1 = FSO.OpenTextFile(File_Out1, 2, True)
Set NFile2 = FSO.OpenTextFile(File_Out2, 2, True)
Set NFile3 = FSO.OpenTextFile(File_Out3, 2, True) 
Set DateFile = FSO.OpenTextFile(File_Date, 2, True)
Set NoSNMP = FSO.OpenTextFile(File_NoSNMP, 2, True) 









Dim arrComputers(256)
k = 0
For i = 0 To 0
 For j = 0 To 255
  arrComputers(k) = "127.0." + CStr(i) + "." + CStr(j)
  k = k + 1
 Next
Next



Dim strComputer

Dim objSWbemServicesEx
Dim objSWbemSink
Dim objSWbemNamedValueSet

Dim lngCount
Dim lngQueueCurrLength, lngQueueMaxLength
Dim i



' Максимальная длина очереди (в данном примере — сколько машин будут пинговаться одновременно),
' выбирается произвольно
lngQueueMaxLength  = 10
' Текущая длина очереди
lngQueueCurrLength = 0

lngCount = UBound(arrComputers)
i = 0

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

While (i <= lngCount) Or (lngQueueCurrLength > 0) ' Пингуем пока не кончатся компы и очередь
    If (i <= lngCount) And (lngQueueCurrLength < lngQueueMaxLength) Then
       
        ' В коллекции «objSWbemNamedValueSet» будем передавать адрес/имя хоста (замечание: в данном конкретном случае
        ' сие, в принципе, необязательно, поскольку класс Win32_PingStatus и так содержит
        ' свойство «.Address», но тут показана сама технология передачи данных в процедуру асинхронной обработки)
        Set objSWbemNamedValueSet = WScript.CreateObject("WbemScripting.SWbemNamedValueSet")
        objSWbemNamedValueSet.Add "HostName", arrComputers(i)
       
        ' Все запросы будут обрабатываться в единственной процедуре обработки
        objSWbemServicesEx.ExecQueryAsync objSWbemSink, "SELECT * FROM Win32_PingStatus WHERE ADDRESS = '" & arrComputers(i) & "'", , , , objSWbemNamedValueSet
       
        i = i + 1
        lngQueueCurrLength = lngQueueCurrLength + 1
    Else
        ' Ожидаем, пока не будут обработаны все асинхронные запросы
        WScript.Sleep 100
    End If
Wend

objSWbemSink.Cancel

Set objSWbemSink      = Nothing
Set objSWbemServicesEx = Nothing
NFile1.Close
NFile2.Close
NFile3.Close
NoSNMP.Close
DateFile.Close

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

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

          objWmiNamedValueSet.Add "AgentAddress", strComputer
          objWmiNamedValueSet.Add "AgentReadCommunityName", "public"
'on error resume next



          If ClassExists(objWmiServices, "SNMP_RFC1213_MIB_system") Then
          Set colSystem = objWmiServices.ExecQuery("SELECT sysName FROM SNMP_RFC1213_MIB_system",,, objWmiNamedValueSet)


          For Each objSystem In colSystem
                                           
            If (Right(objSystem.sysName,12)=".12345678901") Then             
              objSystem.sysName=Left(objSystem.sysName,Len(objSystem.sysName)-12) + ".m"
            Else 
              objSystem.sysName=objSystem.sysName + ".m"             
            End If
            NFile1.WriteLine objSystem.sysName + "        IN        A        " + strComputer 
          Next
          Else
          '  WScript.Echo "OK"
            NoSNMP.WriteLine strComputer
          End If
 

  End If
  End If
End Sub
'=============================================================================

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

'==============================================================================

Function ClassExists(objSWbemServicesEx, strClassName)
        Dim objSWbemObjectEx
       
        ClassExists = False
       
        For Each objSWbemObjectEx In objSWbemServicesEx.SubclassesOf()
                If StrComp(objSWbemObjectEx.Path_.RelPath, strClassName, vbTextCompare) = 0 Then
                        ClassExists = True
    '                  WScript.Echo "GOOD"
                       
                        Exit Function
                End If
        Next       
  '      WScript.Echo "BAD"

End Function



Время: 17:21.

Время: 17:21.
© OSzone.net 2001-