Экзамены Microsoft

Microsoft 2003 Server
Windows 2000

Сторонний софт

Citrix MetaFrame

Подписка на новости

Новости раздела Инструкции
feed image

Опрос

Нужна ли России своя операционная система?





      Яндекс цитирования
      Rambler's Top100
     
      Находится в каталоге Апорт





Печать E-mail

Удаленное администрирование с помощью WMI

Боб Уэллс
04.04.2003

Похоже, в Редмонде набирает силу новая тенденция.

Административные инструменты и утилиты командной строки, область действия которых в прошлом ограничивалась локальным компьютером, превращаются в мощные средства дистанционного администрирования. Стимулом для преобразований послужило появление технологии Windows Management Instrumentation (WMI), на основе которой создаются инструменты.

Не нужно забывать, что WMI с самого начала была разработана для удаленных сценариев администрирования. Любая задача, решаемая локально с помощью WMI-совместимого инструмента, может быть выполнена и дистанционно. В данной статье приводится несколько сценариев, которые наглядно демонстрируют возможности удаленного администрирования с WMI. Сначала речь пойдет о простом WMI-сценарии для выполнения административных задач на локальном компьютере. Затем я покажу, как можно преобразовать этот сценарий для удаленного управления. И, наконец, мы рассмотрим, как запустить сценарий на всех компьютерах удаленной IP-подсети.

Статья рассчитана на тех читателей, которые уже имеют базовые знания о WMI и WMI-сценариях. Хорошее руководство для начинающих — «WMI Scripting Primer: Part 1» (http://msdn.microsoft.com/library/en-us/dnclinic/ html/scripting06112002.asp) компании Microsoft.

Решение для любых задач

Административная задача, которую я хочу выполнить на локальном компьютере, — проверка типа запуска (Startup Type) и статуса службы Telnet. Прежде чем читатели попросят избавить их от очередного сценария, я поспешу предупредить, что тип задачи не имеет значения. Вместо этой задачи можно взять любой из сотен WMI-сценариев, опубликованных на сайте Microsoft TechNet Script Center (http://www.microsoft.com/technet/scriptcenter). Цель данной статьи — показать, как преобразовать типичный сценарий для обслуживания сотен и тысяч удаленных компьютеров.

В Листинге 1 показана локальная версия сценария Telnet Server с подходящим названием TelnetCheck.vbs. Сценарий начинается с инициализации переменной strComputer строкой, состоящей из единственной точки. В сценариях WMI точка представляет локальный компьютер. Поскольку сценарий выполняется на локальном компьютере, я мог бы пропустить переменную strComputer, но, изолировав целевой компьютер с переменной (как показано в Листинге 1), проще приспособить сценарий к работе с удаленными машинами.

Листинг 1. TelnetCheck.vbs.

strComputer = «.»
Set objWMIService = GetObject(«winmgmts:{impersonationLevel=Impersonate}!\\»  & _
 strComputer & «\root\cimv2»)
Set colServices = objWMIService.ExecQuery(«SELECT * FROM Win32_Service « &  _
 «WHERE Name=’tlntsvr’»)
If colServices.Count = 0 Then
 WScript.Echo strComputer & «,Telnet not installed.»
 Else
 For Each objService In colServices
 WScript.Echo objService.SystemName & «,» & _
 objService.StartMode & «,» & _
 objService.State
 Next
 End If
 

Функция GetObject обеспечивает соединение с WMI-службой на целевом компьютере. Строка, передаваемая сценарием в функцию GetObject, представляет собой строку связи WMI (моникер), состоящую из трех компонентов:

  • обязательный префикс WMI, "winmgmts:";
  • параметры безопасности, которые указывают WMI на необходимость имперсонализации вызывающего пользователя или программы (т. е. использование контекста безопасности лица или процесса, запускающего сценарий для организации соединения);
  • путь к объекту WMI, с которым нужно установить связь на целевом компьютере, состоящий из имени целевого компьютера и пространства имен WMI.

Функция GetObject возвращает ссылку на объект SWbemServices из библиотеки сценариев WMI, который представляет аутентифицированное соединение с WMI на локальном или удаленном компьютере. Более подробно о строке связи WMI рассказано в статье «WMI Monikers» (опубликованной по адресу: http://www.winnetmag.ru/win2000/worknt/701.htm).

После того как соединение установлено, сценарий в Листинге 1 вызывает метод SWbemServices ExecQuery, чтобы извлечь экземпляр класса Win32_Service, который представляет службу Telnet. ExecQuery возвращает ссылку на набор SWbemObjectSet — еще один объект автоматизации в библиотеке сценариев WMI. Если служба Telnet на целевом компьютере установлена, то ExecQuery возвращает набор, содержащий только один элемент, который ставится в соответствие переменной ссылочного типа с именем colServices. Если Telnet не установлена, то ExecQuery возвращает пустой набор. Свойство SWbemObjectSet Count используется для того, чтобы определить, есть ли на целевом компьютере Telnet. Если значение свойства Count равно 0, то метод WScript Echo пересылает на консоль сообщение, указывающее, что Telnet не установлена. В противном случае метод Echo передает Startup Type (свойство Win32_Service StartMode) и Status (свойство Win32_Service State) службы Telnet.

Чтобы запустить сценарий, приведенный в Листинге 1, нужно открыть командную строку и ввести с клавиатуры (предполагается, что сценарий сохранен в каталоге с именем C:\scripts):

C:\scripts>cscript telnetcheck.vbs

Если Telnet на локальном компьютере имеется, то на экране появится сообщение, аналогичное отображаемому на консоли:

ATL-LAB-01,Disabled,Stopped

Дистанционные сценарии

Нетрудно догадаться, что для переноса сценария в Листинге 1 на удаленные компьютеры достаточно заменить значение переменной strComputer на имя любого WMI-совместимого компьютера в данном домене. Например, чтобы запустить сценарий на удаленном компьютере с именем ATL-WEB-01, достаточно заменить

strComputer = «.»

на

strComputer = «atl-web-01»

Конечно, на практике невозможно изменять сценарий каждый раз, когда требуется запустить его на новом удаленном компьютере. Более удачное решение — указать имя удаленного компьютера в командной строке в качестве аргумента, как показано в Листинге 2.

Листинг 2. Удаленная утилита командной строки TelnetCheck.vbs с аргументом.
If WScript.Arguments.Count > 0 Then
   strComputer = WScript.Arguments.Item(0)
Else
   strComputer = «.»
End If

Set objWMIService = GetObject(«winmgmts:{impersonationLevel=Impersonate}!\\» & _
	strComputer & «\root\cimv2»)

Set colServices = objWMIService.ExecQuery(«SELECT * FROM Win32_Service « & _
	   «WHERE Name=’tlntsvr’»)

If colServices.Count = 0 Then
   WScript.Echo strComputer & «,Telnet not installed.»
Else
   For Each objService In colServices
      WScript.Echo objService.SystemName & «,» & _
	objService.StartMode  & «,» & _
	objService.State
   Next
End If

Единственное различие между Листингами 1 и 2 — замена строки инициализации strComputer в Листинге 1 подпрограммой A в Листинге 2. Оператор If...Then...Else в подпрограмме A проверяет, есть ли в командной строке аргумент. Если аргумент сценарию передан, то переменной strComputer присваивается значение аргумента. В противном случае strComputer инициализируется точкой, которая представляет локальный компьютер. В остальном Листинг 1 идентичен Листингу 2.

Следующая команда показывает, как запустить сценарий в Листинге 2 на удаленном компьютере с именем ATL-WEB-01:

C:\scripts>cscript
telnetcheck.vbs atl-web-01

Легкость удаленного доступа подчеркивает одну из важнейших особенностей WMI: любая локальная задача может быть выполнена дистанционно. WMI использует распределенную модель объектов Distributed COM (DCOM), в которой для доступа к удаленным компьютерам, в свою очередь, применяется вызов удаленных процедур (remote procedure call, RPC) через подходящий сетевой транспорт. Простота удаленного администрирования WMI может вызвать у администратора ощущение уязвимости, однако по умолчанию дистанционный доступ к удаленному компьютеру через WMI возможен только при наличии у пользователя полномочий уровня Administrator. При отсутствии таких полномочий попытка запустить сценарий из Листинга 2 на удаленном WMI-совместимом компьютере приведет к ошибке Permission denied функции GetObject.

Можно посоветовать следующее: чтобы подготовить сотни WMI-сценариев, хранящихся в Script Center, для дистанционного применения, нужно просто заменить строку

strComputer = «.»

в сценарии Microsoft подпрограмn мой A из Листинга 2. В результате мгновенно формируются сотни сценариев, пригодных для работы с удаленными компьютерами; пользователь должен лишь указать имя удаленной машины в командной строке при запуске сценария.

Дистанционное управление всей IP-подсетью

Наряду с именами NetBIOS, для идентификации удаленных компьютеров можно использовать имена DNS и IP-адреса. Предположим, что компьютеру с именем ATL-WEB-01 из домена atl.acme.com назначен IP-адрес 192.168.0.3. Для обращения к удаленному компьютеру из сценария, показанного в Листинге 2, можно применить любой из перечисленных ниже способов:

strComputer = «atl-web-01»
strComputer = «192.168.0.3»
strComputer = «atl-web-01.atl.acme.com»

Благодаря распознаванию имен DNS и IP-адресов открываются дополнительные возможности видоизменения сценариев. Например, сценарий в Листинге 3 показывает, как запустить WMI-сценарий во всей IP-подсети.

Листинг 3. TelnetCheck.vbs для удаленной подсети IP.
strIPSubnet = «192.168.0.»

Set objShell = CreateObject(«WScript.Shell»)

On Error Resume Next
For strIPNode = 1 To 254

    strComputer = strIPSubnet & strIPNode

    Set objScriptExec = objShell.Exec(«ping -n 2 -w 1000 « & strComputer)
    strPingStdOut = LCase(objScriptExec.StdOut.ReadAll)

    If InStr(strPingStdOut, «reply from « & strComputer) 
Then
    Set objWMIService = GetObject(«winmgmts:» & _
		«{impersonationLevel=Impersonate}!\\» & _
		strComputer & «\root\cimv2»)
    If Err.Number <> 0 Then
	WScript.Echo strComputer & «: « & Err.Description
	Err.Clear
    Else
	Set colServices = objWMIService.ExecQuery _
		(«SELECT * FROM Win32_Service WHERE Name=’tlntsvr’»)
	If colServices.Count = 0 Then
		WScript.Echo strComputer & «: Telnet not installed.»
	Else
		For Each objService In colServices
	                           WScript.Echo objService.SystemName & «: « & _
		                	   objService.StartMode  & «,»  & _
			   objService.State
		Next
	End If
	End If
    Else
	 WScript.Echo strComputer & «: Host unreachable»
    End If
Next

Листинг 3 начинается с инициализации переменной strIPSubnet сетевым адресом целевой подсети. В данном примере используется частная сеть 192.168.0.0/24 класса C. Затем сценарий создает объект Windows Script Host (WSH) Shell. Объект Shell, на который указывает переменная objShell, будет вызывать метод Exec объекта Shell (чуть ниже объясняется, почему). Кроме того, сценарий активизирует механизм обработки ошибок VBScript, On Error Resume Next, чтобы перехватить ошибку, которая возникает при попытке сценария установить связь с WMI-несовместимым устройством или с WMI-совместимым компьютером при отсутствии административных полномочий.

Настоящая работа начинается в цикле For. При каждом повторении цикла For увеличивается счетчик с именем strIPNode. Счетчик strIPNode представляет базовую часть целевого IP-адреса. Первое действие в теле цикла For объединяет текущее значение strIPNode с strIPSubnet и сохраняет результирующую строку в strComputer.

Затем сценарий использует метод Exec объекта WSH Shell и утилиту ping.exe операционной системы для тестирования целевого компьютера. Необходимость предварительного тестирования вызвана особенностями работы WMI-соединений. В типичных условиях тайм-аута WMI приходится ждать довольно долго — не менее 1 мин. Если большое число компьютеров в целевой подсети работает в автономном режиме и недоступно, то время выполнения сценария заметно увеличивается.

Например, предположим, что недоступна половина узлов типичной подсети класса C. Если не запустить утилиту Ping, то пройдет несколько часов, пока WMI будет пытаться установить соединение с каждым IP-адресом, и половина попыток закончится тайм-аутом. Благодаря предварительному тестированию каждого компьютера сокращается время, затрачиваемое на определение доступности каждой машины.

Для запуска Ping используется метод Exec объекта WSH Shell. Чтобы управлять работой Ping, число посылаемых запросов Ping уменьшено до 2 (-n 2), а время ожидания ответа установлено равным 1000 мс (-w 1000). В результате ожидание длительностью 60 с и более (тайм-аут WMI-соединения) сокращается до нескольких секунд.

Метод Exec возвращает ссылку на объект WshScriptExec, которую сценарий может применять для взаимодействия и управления процессом. Я использую полученную ссылку objScriptExec для перехвата выходных данных утилиты Ping, которые затем преобразуются в нижний регистр и сохраняются в переменной strPingStdOut. Далее, отыскивая с помощью функции InStr подстроку reply from (за которой следует целевой IP-адрес) в выходных данных Ping, я выясняю, успешно ли завершилась работа Ping. Если это так, то фрагмент сценария с меткой A пытается установить WMI-соединение с удаленным компьютером, IP-адрес которого сохранен в ссылках strComputer. Вызов GetObject идентичен вызову GetObject, приведенному в Листингах 1 и 2.

Хотя я тестировал узел, чтобы проверить, подключен ли он к сети, вызов GetObject может закончиться неудачей, если в strComputer указан IP-адрес WMI-несовместимого компьютера или контекст безопасности, в котором исполняется сценарий, не имеет прав административного доступа к удаленному компьютеру. Оператор On Error Resume Next (активизированный ранее) и код проверки ошибки, расположенный сразу за вызовом GetObject, перехватывают обе ошибки.

Оставшаяся часть Листинга 3 — после того как соединение WMI установлено — идентична Листингам 1 и 2. Ниже приведена часть выходных данных, генерируемых Листингом 3.

ATL-LAB-01: Disabled,Stopped
ATL-DC-01: Manual,Stopped
ATL-WEB-01: Disabled,Stopped
192.168.0.4: Permission denied
192.168.0.5: Telnet not installed.
192.168.0.6: Telnet not installed.
192.168.0.7: Host unreachable

Узел с IP-адресом 192.168.0.4 — компьютер Windows XP Home Edition, с которым нельзя установить WMI-соединение.

Чтобы запустить сценарий Листинга 3 в диапазоне IP-адресов сети, необходимо изменить значение переменной strIPSubnet и начальную и конечную величины, назначенные strIPNode в операторе For. Кроме того, следует убедиться, что используется версия WSH 5.6, в которой реализован метод Exec объекта Shell.

Практическое применение

Приспособить Листинг 3 для запуска одного из WMI-сценариев, хранящихся в Script Center, не так уж сложно.

Предположим, требуется запустить сценарий Restart a Computer (http://www.microsoft.com/technet/scriptcenter/ compmgmt/scrcm38.asp) на всех компьютерах в указанном диапазоне IP-адресов. Необходимо выполнить следующие действия.

  1. Заменить исходный текст с меткой A Листинга 3 вызовом GetObject в сценарии Microsoft:
    objWMIService =
    GetObject("winmgmts:" & _
    "{impersonationLevel=impersonate," & _
    "(Shutdown)}!\\" & strComputer & _
    "\root\cimv2")
  2. Заменить исходный текст с меткой B Листинга 3 вызовом ExecQuery в сценарии Microsoft:
    colOperatingSystems = _
    objWMIService.ExecQuery _
    ("Select * from _
    Win32_OperatingSystem")
  3. Заменить исходный текст с меткой C Листинга 3 циклом For Each в сценарии Microsoft:
    Each objOperatingSystem in _
    colOperatingSystems _
    ObjOperatingSystem.Reboot()
    Next

В Листинге 4 показан окончательный сценарий. При запуске сценария в сети необходимо соблюдать осторожность: если компьютер, уже выполняющий данный сценарий, находится в диапазоне IP-адресов целевой подсети, то он также будет перезапущен. В этом случае можно дополнить тело основного цикла For условным оператором (If...Then...Else), чтобы сценарий пропустил локальный компьютер. Применив описанные выше действия к большинству WMI-сценариев Script Center, можно превратить локальный сценарий в мощный корпоративный инструмент.

Листинг 4. RebootSubnet.vbs.
Listing 4: RebootSubnet.vbs

strIPSubnet = «192.168.0.»

Set objShell = CreateObject(«WScript.Shell»)

On Error Resume Next
For strIPNode = 1 To 254

    strComputer = strIPSubnet & strIPNode

    Set objScriptExec = objShell.Exec(«ping -n 2 -w 1000 « & strComputer)
    strPingStdOut = LCase(objScriptExec.StdOut.ReadAll)

    If InStr(strPingStdOut, «reply from « & strComputer) Then
	Set objWMIService = GetObject(«winmgmts:» & _
	        «{impersonationLevel=impersonate,(Shutdown)}!\\» & _
	        strComputer & «\root\cimv2»)
        If Err.Number <> 0 Then
	     WScript.Echo strComputer & «: « & Err.Description
	     Err.Clear
        Else
	   Set colOperatingSystems = objWMIService.ExecQuery _
	              («SELECT * FROM Win32_OperatingSystem»)
	   For Each objOperatingSystem in colOperatingSystems
		objOperatingSystem.Reboot()
	   Next
       End If
    Else
	WScript.Echo strComputer & «: Host unreachable»
   End If
Next

Проблема безопасности

WMI защищена достаточно надежно. В данной статье я не могу подробно рассказать о тонкостях защиты WMI, отвечу только на основные вопросы. Более полно проблема безопасности будет рассмотрена в следующей статье.

В WMI используется несколько контрольных уровней безопасности. Первый из них уже упоминался: контроль полномочий WMI. Полномочия WMI реализованы на уровне пространства имен (\root\cimv2) и проверяются при организации соединения WMI с локальным или удаленным компьютером. Для управления полномочиями WMI используется оснастка WMI Control консоли Microsoft Management Console (MMC). По умолчанию администраторы — единственные доверенные лица, которым предоставляется право Remote Enable.

Второй уровень контроля — безопасность DCOM. Стандартный режим DCOM для WMI — имперсонализация вызывающего сценарий пользователя или процесса. Третий и последний уровень контроля — подсистема безопасности операционной системы. Базовое правило подразумевает, что WMI не предоставляет доступ ни к одному объекту, к которому пользователь или процесс еще не обращались.

И, наконец, о роли браузера. Все объекты в библиотеке сценариев WMI (например, SWbemServices, SWbemObject) отмечены как небезопасные. Поэтому, если пользователи не ослабили режим безопасности браузера, он защищен надежно. Но если пользователи изменили параметры защиты браузера, сделав его более уязвимым, следует применить системную политику для управления режимом безопасности организации.

Боб Уэллс — консультант по программному обеспечению; специализируется на вопросах проектирования и реализации инфраструктуры информационных систем на базе NT. Имеет сертификаты MCSE и MCT. С ним можно связаться по адресу: Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script .
Журнал "Windows & .NET Magazine/RE", #02, 2003 год //
Издательство "Открытые системы" (www.osp.ru)

Постоянный адрес статьи: http://www.osp.ru/win2000/2003/02/016.htm
 

Тематические ссылки от Яндекса

Реклама





Реклама


Товары в сети


Реклама