Управление сетями Windows с помощью сценариев. Часть 7. Устранение загадочной ошибки

Опубликовано: 23 Марта, 2023

  • Управление сетями Windows с помощью сценариев. Часть 9. Общие сведения об удаленных сценариях
  • Управление сетями Windows с помощью скриптов. Часть 10. Приемы удаленного скриптинга
  • Управление сетями Windows с помощью сценариев. Часть 11. Дополнительные приемы работы со сценариями
  • Управление сетями Windows с помощью сценариев. Часть 12. Свойства класса WMI
  • Управление сетями Windows с помощью сценариев. Часть 13. Удобный сценарий возврата всех значений
  • Управление сетями Windows с помощью сценариев. Часть 14. Дополнительные сведения о сценариях WMI

В предыдущей статье мы взяли наш сценарий ChangeIPAddress.vbs, разработанный ранее, и модифицировали его, чтобы использовать его для изменения IP-адреса на удаленном компьютере. Вот как выглядел наш модифицированный скрипт:

Опция явная
Дим objWMIService
Dim objNetAdapter
Dim strКомпьютер
Дим улАдрес
Dim arrIP-адрес
Dim arrSubnetMask
Dim colNetAdapters
Dim errEnableStatic

Если WScript.Arguments.Count = 0 Тогда
Wscript.Echo «Использование: ChangeIPAddress.vbs новый_IP_адрес»
WScript.Выход
Конец, если

стрКомпьютер = «xp2»
strAddress = Wscript.Аргументы.Элемент (0)
arrIP-адрес = Массив (strAddress)
arrSubnetMask = Массив («255.255.255.0»)
Установите objWMIService = GetObject("winmgmts:\" & strComputer & " ootcimv2")
Установите colNetAdapters = objWMIService.ExecQuery («Выберите * из Win32_NetworkAdapterConfiguration, где IPEnabled = TRUE»)
Для каждого objNetAdapter в colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Следующий

Линия:

стрКомпьютер = «xp2»

сообщает нам, что компьютер, на который нацелен сценарий, имеет имя XP2. Удаленный компьютер XP2 изначально имел IP-адрес 172.16.11.43.


Оформите предзаказ на копию Microsoft Windows Vista Resource Kit уже сегодня!

Теперь, когда мы запустили этот сценарий, набрав ChangeIPAddress.vbs 172.16.11.65 с рабочей станции администратора с именем XP, произошло следующее:

  1. Скрипт сработал, т.е. адрес XP2 изменился с 172.16.11.43 на 172.16.11.65.
  2. Скрипт долго выполнялся.
  3. Сценарий вернул следующую ошибку: C: oolsChangeIPAddress.vbs(23, 6) SWbemObjectEx: Ошибка удаленного вызова процедуры.

Как нам относиться к этим результатам?

Простое решение

Единственное, что мы могли бы сделать, это сказать: «Ну, раз это сработало, давайте просто проигнорируем ошибку». С таким подходом есть что сказать. В конце концов, любой реальный администратор знает, что ИТ — это не точная наука, и мы часто прибегаем к «обходным путям» для проблем, когда не можем найти подходящие решения для них.

Итак, как мы можем игнорировать ошибку? Просто добавьте следующую строку в начале раздела заголовка:

При ошибке Возобновить Далее

Другими словами, наш раздел заголовка теперь будет выглядеть так:

Опция явная
При ошибке Возобновить Далее
Дим objWMIService
и т.п.

Теперь мы не видим ошибки, и наш скрипт работает. Но выполнение все еще занимает много времени, на самом деле больше минуты. В чем дело?

Устранение неполадок с сообщением об ошибке

Сообщения об ошибках иногда загадочны, и это одно из них. Вот снова сообщение об ошибке:

SWbemObjectEx: Ошибка удаленного вызова процедуры.

И вот строка кода, которая его генерирует:

errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

Теперь эта строка кода работает (т.е. IP-адрес на целевом компьютере меняется), но затем выдает ошибку. Почему?

Начнем с попытки понять, что означает SWebObjectEx. Быстрый поиск в MSDN находит эту страницу, на которой написано следующее:

Расширяет функциональность SWbemObject. Этот объект добавляет метод Refresh для объектов SWbemRefresher.

Итак, SWbemObjectEx в основном просто добавляет больше функциональности в SWbemObject. Так что же такое SWbemObject?

Содержит и управляет одним классом объектов WMI или экземпляром.

Хорошо, что это значит? Эта страница говорит нам больше, но она ужасно гиковская. Проще говоря, SWbemObject (и, следовательно, SWbemObjectEx) — это все, чем вы управляете или запрашиваете в WMI. В нашем сценарии мы запрашиваем класс Win32_NetworkAdapterConfiguration и возвращаем коллекцию объектов с именем colNetAdapters, представляющих сетевые адаптеры на компьютере. Таким образом, SWbemObjectEx (или SWbemObject), упомянутый в этом сообщении об ошибке, является просто объектом, представляющим сам сетевой адаптер, т. е. objNetAdapter.

Итак, objNetAdapter генерирует ошибку. Почему?

Что ж, мне пришлось поговорить с некоторыми моими друзьями, которые являются «гуру» по написанию сценариев, чтобы попытаться понять это. И лучший ответ, который я получил на сегодняшний день, не является полностью удовлетворительным, но эй, когда вообще «удовлетворение» было частью описания работы для ИТ-администратора?

Во всяком случае, вот в чем проблема. По словам одного из этих гуру, кажется, что «что-то» в одном из исправлений для Windows XP могло изменить способ создания и отправки обратного вызова при выполнении оператора, вызвавшего ошибку. Обычно, если вызов метода EnableStatic экземпляра объекта класса Win32_NetworkAdapterConfiguration завершается успешно, он возвращает 0, что означает отсутствие ошибки, а если вызов возвращает 1, это означает, что требуется перезагрузка (дополнительную информацию см. на этой странице в разделе «Возвращаемое значение»). ). Разумеется, в Windows XP при изменении IP-адреса сетевого адаптера перезагрузка не требуется. Если по какой-то причине исправление могло изменить что-то в провайдере WMI или каком-то другом скрытом элементе, так что Windows считает, что требуется перезагрузка, прежде чем новый адрес сможет «принять» на целевой машине, и это генерирует ошибку, потому что конфигурация сетевого адаптера на машине остается в неопределенном состоянии до перезагрузки машины. Но поскольку сценарий все еще выполняется на рабочей станции администратора, когда конфигурация сетевого адаптера целевого компьютера переходит в неопределенное состояние, RPC-соединение между двумя машинами разрывается до того, как сценарий завершит работу. Отсюда ошибка.

По крайней мере, это лучший ответ, который у меня есть на этот вопрос в настоящее время, и я продолжу расследование. Но тем временем давайте посмотрим, сможем ли мы как-то подтвердить, что эта проблема является изолированной, т. е. что ошибка связана только с методом EnableStatic Win32_NetworkAdapterConfiguration, а не с чем-то более общим. Что, если мы попробуем написать другой сценарий, который делает что-то другое с сетевым адаптером на целевой машине вместо изменения его IP-адреса? Например, как насчет того, чтобы попытаться изменить шлюз по умолчанию вместо IP-адреса на целевой машине? Если это работает, то, по крайней мере, мы знаем, что можем успешно подключиться с нашей рабочей станции администратора к удаленному компьютеру и вызвать метод WMI, чтобы изменить на нем сетевые настройки.

Изменение шлюза по умолчанию

На данный момент я хотел бы предложить вам прекратить чтение этой статьи и вернуться к части 4 этой серии, где я покажу вам, как использовать MSDN, чтобы узнать, как использовать свойства и методы класса Win32_NetworkAdapterConfiguration. Бьюсь об заклад, сделав это, вы сможете написать такой сценарий самостоятельно. Попытайся!

АНТРАКТ

Хорошо, теперь вы попытались написать свой собственный сценарий, и, возможно, он сработал, а может быть, и нет. Если это не сработало, выполните следующие действия:

  1. Сначала перейдите на страницу MSDN для класса Win32_NetworkAdapterConfiguration.
  2. Найдите на странице метод, связанный со сменой шлюза на сетевом адаптере. Беглый просмотр этой страницы покажет следующее:
    SetGateways — указывает список шлюзов для маршрутизации пакетов, предназначенных для другой подсети, отличной от той, к которой подключен этот адаптер.
    Это должно быть то, что мы хотим, поэтому щелкните SetGateways, чтобы открыть метод SetGateways на странице класса Win32_NetworkAdapterConfiguration.
  3. На странице метода SetGateways вы найдете следующее объяснение:
    Метод класса WMI SetGateways задает список шлюзов для маршрутизации пакетов в подсеть, отличную от подсети, к которой подключен сетевой адаптер. Этот метод работает только тогда, когда сетевая карта (NIC) находится в режиме статического IP.

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

Установить шлюзы (A, B)

Здесь A — строковая переменная, содержащая IP-адрес шлюза, а B — целое число от 1 до 9999, указывающее метрику.

Теперь у вас должно быть достаточно информации для написания сценария. Самый простой способ — начать с нашего исходного сценария ChangeIPAddress.vbs, найденного во второй части этой серии, и немного изменить его, пока не будет получен новый сценарий (который мы назовем ChangeGateway.vbs ), который выглядит следующим образом:

'==========================
ИМЯ: ChangeGateway.vbs
'
АВТОР: Митч Таллок
ДАТА: февраль 2007 г.
'
«АРГУМЕНТЫ:
'1. адрес_шлюза
2. метрика
'==========================-

Опция явная

Дим objWMIService
Dim objNetAdapter
Dim strКомпьютер
Dim strGateway
Dim arrGateway
Dim intMetric
Dim arrMetric
Dim colNetAdapters
Dim errGateway

'Проверить отсутствующие аргументы

Если WScript.Arguments.Count = 0 Тогда
Wscript.Echo «Использование: метрика ChangeGateway.vbs gateway_address»
WScript.Выйти
Конец, если

стрКомпьютер = «xp2»
strGateway = Wscript.Аргументы.Элемент(0)
arrGateway = Массив (strGateway)
intMetric = Wscript.Аргументы.Элемент(1)
arrMetric = Массив (intMetric)
Установите objWMIService = GetObject("winmgmts:\" & strComputer & " ootcimv2")
Установите colNetAdapters = objWMIService.ExecQuery («Выберите * из Win32_NetworkAdapterConfiguration, где IPEnabled = TRUE»)
Для каждого objNetAdapter в colNetAdapters
errGateway = objNetAdapter.SetGateways(arrGateway, arrMetric)
Следующий

'Показать результат или код ошибки

Если errGateway=0 Тогда
Wscript.Echo «Шлюз адаптера был успешно изменен на » & strGateway
Еще
Wscript.Echo «Смена шлюза адаптера не удалась. Код ошибки ” & errGateway
Конец, если

Скопируйте этот сценарий в Блокнот (с отключенным переносом слов) и сохраните его как ChangeGateway.vbs. Теперь давайте проверим это. Давайте войдем на удаленную машину XP2, откроем командную строку и наберем ipconfig /all и вот результат:

C:> ipconfig /все

IP-конфигурация Windows

Имя хоста............: XP2
Основной DNS-суффикс.......: contoso.com
Тип узла............: Неизвестный
IP-маршрутизация включена........: Нет
Прокси-сервер WINS включен........: Нет

Ethernet-адаптер Подключение по локальной сети:

DNS-суффикс для конкретного подключения.:
Описание...........: PCI Fast Ethernet на базе Intel 21140
Адаптер (общий)
Физический адрес.........: 00-03-FF-21-88-8C
DHCP включен...........: Нет
Айпи адрес............: 172.16.11.80
Маска подсети...........: 255.255.255.0
Шлюз по умолчанию.........: 172.16.11.1

С:>

Теперь на рабочей станции администратора XP давайте откроем командную строку и запустим новый скрипт следующим образом:

C: ools> ChangeGateway.vbs 172.16.11.2 5
Microsoft (R) Windows Script Host версии 5.6
Авторское право (C) Microsoft Corporation 1996-2001. Все права защищены.

Шлюз адаптера был успешно изменен на 172.16.11.2.

C:инструменты>

Скрипт занимает около 5 секунд, и ошибок не возникает. (Обратите внимание, что я пропустил «Возобновить дальше при ошибке» в заголовке моего скрипта, так как я хочу видеть любые ошибки, если они происходят).

Теперь вернемся к удаленной машине XP2 и снова запустим ipconfig /all:

C:> ipconfig /все

IP-конфигурация Windows

Имя хоста............: XP2
Основной DNS-суффикс.......: contoso.com
Тип узла............: Неизвестный
IP-маршрутизация включена........: Нет
Прокси-сервер WINS включен........: Нет

Ethernet-адаптер Подключение по локальной сети:

DNS-суффикс для конкретного подключения.:
Описание...........: PCI Fast Ethernet на базе Intel 21140
Адаптер (общий)
Физический адрес.........: 00-03-FF-21-88-8C
DHCP включен...........: Нет
Айпи адрес............: 172.16.11.80
Маска подсети...........: 255.255.255.0
Шлюз по умолчанию.........: 172.16.11.2

С:>

Это сработало. Никаких ошибок, ничего загадочного — мы запустили сценарий удаленно на другом компьютере, и он изменил шлюз по умолчанию на целевой машине.

Ну, мы не проверили, изменилась ли метрика, не так ли? Команда ipconfig не показывает эту информацию, но мы можем использовать netsh, чтобы получить ее следующим образом:

C:> IP-адрес интерфейса netsh показать адрес

Конфигурация для интерфейса «Подключение по локальной сети»
DHCP включен: Нет
IP-адрес: 172.16.11.80
Маска подсети: 255.255.255.0
Шлюз по умолчанию: 172.16.11.2
Метрика шлюза: 5
Метрика интерфейса: 0

С:>

Да, это работает.

  • Управление сетями Windows с помощью сценариев. Часть 8. Устранение неполадок с удаленными сценариями с помощью Network Monitor 3.0
  • Управление сетями Windows с помощью сценариев. Часть 9. Общие сведения об удаленных сценариях
  • Управление сетями Windows с помощью скриптов. Часть 10. Приемы удаленного скриптинга
  • Управление сетями Windows с помощью сценариев. Часть 11. Дополнительные приемы работы со сценариями
  • Управление сетями Windows с помощью сценариев. Часть 12. Свойства класса WMI
  • Управление сетями Windows с помощью сценариев. Часть 13. Удобный сценарий возврата всех значений
  • Управление сетями Windows с помощью сценариев. Часть 14. Дополнительные сведения о сценариях WMI