Использование инструментария управления окнами (Window Management Instrumentation WMI)
Использование инструментария управления окнами (Window Management Instrumentation, WMI)
Перед тем как перейти еще к одной операционной системе, рассмотрим последний подход к управлению процессами в NT/2000. Этот подход следовало бы назвать «Страной будущего», поскольку в нем используется пока еще не очень распространенная, но уже пробивающаяся технология. Инструментарий управления окнами (WMI) доступен в Windows 2000 (и в NT4.0 с установленным SP4+). Со временем, когда Windows 2000 широко распространится, WMI вполне может стать важной частью администрирования NT/2000.
К сожалению, WMI относится к числу технологий не для слабонервных, потому что очень быстро становится чересчур сложной. Она основана на объектно-ориентированной модели, которая позволяет представить не только данные, но и отношения между объектами. Например, можно создать связь между веб-сервером и дисковым массивом RAID, в котором хранятся данные с этого сервера, обеспечивающую, в случае неисправности массива RAID, сообщение и о проблеме с вебсервером. Не желая вдаваться во все эти сложности, мы дадим здесь лишь поверхностный обзор WMI в небольшом и простом введении, сопровождаемом примерами.
Если вы хотите познакомиться с этой технологией подробнее, я рекомендую загрузить документацию по WMI, обучающее руководство «LearnWBM» и WMI SDK из раздела «WMI» сайта http://msdn.microsoft.com /developer/sdk. Также взгляните на информацию, представленную на веб-сайте Distributed Management Task Force на http:// www.dtmf.org. Тем временем, начнем с краткого экскурса.
WMI - это реализация и расширение (от Microsoft) неудачно названной инициативы Web-Based Enterprise Management или WBEM. И хотя такое название вызывает в воображении что-то связанное с броузерами, эта технология не имеет практически ничего общего с World Wide Web. Компании, входившие в состав Distributed Management Task Force (DMTF), хотели придумать что-то, что могло бы упростить выполнение задач управления при помощи броузеров. Забыв про название, можно сказать, что WBEM определяет модель данных для информации управления. WBEM обеспечивает спецификацию для организации, доступа и перемещения этих данных. WBEM также предлагает связующий интерфейс для работы с данными, доступными из других протоколов, например, Simple Network Management Protocol (SNMP) (о котором мы будем говорить в главе 10 «Безопасность и наблюдение за сетью») и Common Management Information Protocol (CMIP). Данные в WBEM организованы при помощи Общей информационной модели (Common Information Model, CIM). CIM - источник силы и сложности в WBEM/WMI. Она предоставляет расширяемые модели данных, содержащие объекты и классы объектов для любой физической или логической сущности, которой можно захотеть управлять. Например, в ней есть классы объектов для целых сетей и объекты для отдельного слота машины. Существуют объекты для настроек как аппаратного обеспечения, так и приложений программного обеспечения. Помимо этого CIM позволяет определять классы объектов, описывающие связи между другими объектами.
Модель данных документирована в двух частях: в спецификации CIM и схеме CIM. Первая описывает, как (как данные определяются, их связь с другими стандартами управления и т. д.); вторая - что (т. е. сами объекты). Это деление может напомнить о связи SNMP SMI и МШ (подробный материал в главе 10).
На практике вы будете чаще обращаться к схеме CIM, чем к спецификации, когда вы освоитесь с тем, как представляются данные. Формат схемы, названный форматом управляемых объектов (Managed Object Format, MOF), довольно просто читать.
Схема CIM состоит из двух слоев:
- Центральная модель (core model) для объектов и классов, полезна для всех типов взаимодействия WBEM.
- Общая модель (common model) для объектов, которые не зависят от создателя и операционной системы. Внутри общей модели в настоящее время определены пять областей: системы, устройства, приложения, сети и физический уровень.
На вершине этих двух слоев может быть любое число расширенных схем (Extension schema), определяющих объекты и классы для информации, зависящей от создателя и информационной системы.
Самая важная часть WMI, которая отличает ее от обычных реализаций WBEM, - это схема Win32, расширенная схема для информации, специфичной для Win32, построенная на центральной и общей модели. WMI также добавляется к общей структуре WBEM, обеспечивая механизмы доступа к данным CIM, специфичные для Win32. Используя это расширение схемы и набор методов доступа к данным, мы можем выяснить, как управлять процессами из Perl средствами WMI.
Два из этих методов доступа: ODBC (открытый интерфейс взаимодействия с базами данных) и COM/DCOM (модель составных компонентов распределенная модель составных компонентов) будут более полно рассмотрены в других главах этой книги. В примерах будет использоваться модель COM/DCOM, поскольку ODBC разрешает лишь запрашивать информацию у WMI (хотя и в простой, похожей на присущую базам данных манере). COM/DCOM позволяет и запрашивать информацию, и взаимодействовать с ней, что очень важно для «управляющей» части контроля над процессами.
Приведенные далее примеры программ на Perl не выглядят такими уж трудными, и вас могут удивить слова «очень быстро становится чересчур сложным». Приведенный ниже код выглядит простым, потому что:
- Мы касаемся только поверхности WMI. Мы даже не затрагиваем таких понятий, как «ассоциации» (т. е. связи между объектами и классами объектов).
- Мы выполняем только простые операции управления. Управление процессами в таком контексте состоит из опроса исполняемых процессов и возможности их завершения. Эти операции легко осуществляются в WMI при использовании расширения схемы Win32.
- В наших примерах спрятана вся сложность перевода документации WMI и примеров программ с VBscript/JScript на Perl.
- В примерах скрыта неясность процессов отладки. Когда код на Perl, имеющий отношений к WMI, завершается с ошибками, выдается очень мало информации, которая могла бы помочь найти их причину. Да, вы получите сообщения об ошибках, но в них никогда не будет сказано ОШИБКА: ПРОБЛЕМА ЗАКЛЮЧАЕТСЯ В СЛЕДУЮЩЕМ. .. Скорее всего, вы получите что-нибудь подобное wbemErrFailed 0x8004100 или вообще пустую структуру данных. Справедливости ради надо сказать, что большая часть такой неясности возникает благодаря участию Perl в этом процессе. Он действует в качестве интерфейса к целому ряду довольно сложных многоуровневых операций, которые не утруждают себя передачей содержательных сообщений в случае возникновения проблем.
Это звучит довольно мрачно. Поэтому позвольте предложить совет, воспользоваться которым стоит перед тем, как рассматривать сами примеры:
- Изучите любые примеры, использующие модуль Win32. :OLE, которые сможете найти. Список рассылки Win32-Users на ActiveState и его архивы на http://www.activestate.com - хороший источник подобной информации. Если сравнить их с эквивалентными примерами на VBscript, то станут понятны необходимые идиомы трансляции. Кроме того, вам может помочь раздел «ADSI (Интерфейсы активных служб каталогов)» главы 6.
- Подружитесь с отладчиком Perl и используйте его для тщательной проверки фрагментов кода в качестве части процесса обучения. Другой способ тестирования на платформе Win32 отрывков кода на Perl - применение программы TurboPerl Вильяма Смита (William P. Smith), ее можно найти на http://users.erols.com/turboperL/, совместно с модулями dumpvar.pl или Data: :Dumper. В ней бывают сбои (я советую чаще сохранять исправления), но обычно она может помочь в создании заготовок кода на Perl. Другие инструменты интегрированной среды разработки также могут обладать подобными возможностями.
- Всегда держите под рукой копию WMI SDK. Его документация и примеры кода на VBscript очень полезны.
- Чаще используйте броузер объектов WMI в WMI SDK. Он поможет вам разобраться со структурой.
Теперь перейдем к Perl. Первоначальная наша задача - определить, какую информацию о процессах в Win32 можно получить и как ее использовать.
Сначала нужно установить соединение с пространством имен (names расе) WMI. Пространство имен определяется в WMI SDK как «единица для группировки классов и экземпляров для управления их областью действия и видимостью». Нам необходимо соединение с корнем стандартного пространства имен cimv2, в котором содержатся все интересующие нас данные.
Кроме того, потребуется установить соединение с соответствующим уровнем привилегий. Программа должна иметь право отлаживать процесс и представлять нас; другими словами, она должна выполняться от имени пользователя, запустившего сценарий. Установленное соединение позволит получить объект Win32_Procoss (как это определяется в схеме Win32).
Существуют как простой, так и сложный способы создать это соединение. В первом примере будут приведены оба способа, так что читатель сможет решить, чего стоит каждый из них. Вот сложный способ с объяснениями.
use Win32::OLE('in1);
Sserver = ''; 8 соединение с локальной машиной
Я получаем объект SWbemLocator
$lob] = Win32: :OLE->new
( 'WbemScripting, SWoe:riLocat:or')
or die "Невозможно создать объект локатор: ' .Win32: :CLE->LasTf.-"rori
и определяем, что сценарий выполняется с празам!'
# используем зю для пслуче^'р объекта bWbe;rServ:c»^ Ssobj = $iol". ->
or oie M^acjMcvhc создать ооье^.т сеов-' ".Win32 :OLt-.>LastErrcr (). \:V ,
и получаем объект схемы
Sprocschm = $sobj->Get('Win32_Process');
Сложный способ включает в себя:
- Получение объекта локатора, используемого для нахождения соединения с объектом-сервером
- Установку прав, т. е. программа будет выполняться с нашими привилегиями
- Использование этого объекта для получения соединения с ci/w2-пространством имен WMI
- Применение этого соединения для получения объекта Win32_Process
Все это можно сделать за один шаг, если использовать COM moniker's display name. В соответствии с WMI SDK, «в модели составных объектов (СОМ) моникер - это стандартный механизм для инкапсуляции местоположения другого СОМ-объекта и связи с ним. Текстовое представление моникера называется отображаемым именем». Вот и простой способ в действии:
usa Win32::OLECirT);
Sprocschm = Win32::OLE->GetObject(
'winmgmts: {impersonationLevel=impersonate}! Wiri32_Process ')
or die "Невозможно создать объект сервера: ".Win32: :OLE->LastError()."\n":
Теперь, когда у нас есть объект Win32_Process, можно с его помощью получить нужные части схемы, представляющие собой процессы в Win32. В их число входят все доступные свойства и методы Win32_Pro-cess, которые годятся к употреблению. Применяемая программа довольно проста; единственно, что не вполне очевидно, - это использование оператора in в Win32: :01_Е. Чтобы объяснить это, нам придется немного отклониться от темы.
Объект $procschm имеет два специальных свойства: Properties и Methods. В каждом из них хранится специальный дочерний объект, известный как collection object в терминологии СОМ. Объект collection object является родительским контейнером для других объектов; в этом случае в них хранятся объекты описания свойств (Properties_) и методов (Methods) схемы. Оператор in возвращает массив ссылок на каждый дочерний объект контейнера. Располагая таким массивом, можно обойти все его элементы в цикле, возвращая на каждой итерации свойство Name каждого дочернего объекта. О других известных применениях in можно узнать из раздела «ADSI (Интерфейсы активных служб каталогов)» главы 6. Вот как выглядит сама программа:
use Win32::OLE('in'):
соединяемся с пространством имен, даем указание действовать
с правами пользователя и получаем объект Win32_process,
просто используя отображаемое имя
Sprocschm = Win32 -OLE->GetObject(
'winmgmtr, : {impersor,ationl_evel = impersonate} ' win32._Process )
or die "Невозможно создать объект сервера: " .i/nn32' .OLE- > Last etc :().
print "--- Prope-ties ---\n";
print join("\n" , map {$_->{Name}
}
(in $procschm->{Properties_} )}:
print "\n--- Methods ---\n";
printoin("\n",map {$_->{Name}
}
(in $procschm->{Methods_l ;}:
Вывод (на машине с NT4.0) выглядит примерно так:
— Properties —
Caption
CreationCiassName
CreationDate
CSCreationClassName
CSName
Description
ExecutablePath
ExecutionState
Handle
InstallDate
KernelModeTime
MaximumWorkingSetSize
MinimumWorkingSetSize
Name
OSCreationClassName
OSNarne
PageFaults
PageFilellsage
PeakPageFileUsage
PeakWorkingSetSize
Priority
Processld
QuotaNonPagedPoolUsage
QuotaPagedPoolUsage
QuotaPeakNonPagedPoolUsage
QuotaPeakPagedPoolUsage
Status
TerminationDate
User'ModeTime
WindowsVersion
WorkingSetSize
--- Methods ---
Create
Terminate
GetOwner
GetOwrierSui
Рассмотрим это подробнее. Чтобы получить список запущенных процессов, нужно запросить все экземпляры объектов Win32_Process:
use Win32::OLE('in'):
it выполняем все первоначальные шаги в одном цикле
$sob] = Win32::OLE->GetOcject(
'winmgmts:{impersonationLeveI=inpersorate}') or die
"Невозможно создать объект сервера: ".Win32: :OLE->LastError() "V"
foreach Sprocess (in $sobj->InstancesOf("Win32_Process")){
print $process->{Name)." имеет pid #".$process->{Process!d}, "\n"; }
Первоначальное отображаемое имя не включает путь к определенному объекту (т. е. мы отбросили ! Win32_Process). Итак, получен объект связи с сервером. В результате вызова метод InstancesOf () возвращает объект-коллекцию (collection object), который содержит все экземпляры конкретного объекта. Наш код обращается к каждому объекту и выводит его свойства Name и Processld. В итоге, у нас есть список всех запущенных процессов.
Чуть менее великодушный подход к обойденным в цикле процессам позволил бы использовать один из методов, указанных в приведенном выше списке:
foreach $process (in $sobj->InstancesOf ("Win32__Process")){
$process->Terminate(1); }
В результате, все работающие процессы будут завершены. Я не рекомендую вам запускать эту программу в таком виде; подправьте ее в соответствии с вашими нуждами, сделав более конкретной.
Теперь у вас есть необходимые знания, чтобы начать использовать WMI для управления процессами. В WMI есть \Уш32-расширения для многих других частей операционной системы, включая реестр и журнал событий.
Вот и все, что мы хотели сказать об управлении процессами в WinNT и 2000. Теперь перейдем к последней операционной системе.