Константин Леонтьев
Вы всё ещё не используете WMI?
Часть II: пишем сценарии
Продолжаем изучение технологии WMI и способов ее применения в повседневной практике системного администрирования. Настало время перейти к теме написания скриптов, использующих WMI для управления нашей распределенной сетевой инфраструктурой.
Пишем сценарии с использованием WMI
Еще раз взгляните на изображение архитектуры WMI, которое я поместил в начало первой части статьи [1], рис. 1. Обратите внимание, что доступ к WMI может осуществляться через интерфейсы COM+ и .NET Framework. Это означает, что любой язык программирования, который поддерживает взаимодействие с Microsoft Windows COM+ и .NET Framework, может использоваться для работы с WMI. К перечню таких языков, в частности, относятся: VBScript, Visual Basic и Visual Basic .NET, Java Script, Python, Perl, PHP, C#, C++, Pascal, TCL и другие.
Обращение к объектам и методам WMI в разных языках может немного отличаться из-за специфики синтаксиса работы с объектами и типами для каждого конкретного языка, но в целом все приемы очень сходны.
Для иллюстрации приведу несколько примеров (см. листинги 1-6). Ознакомившись с ними, очевидно, что неважно, какой язык вы выберите, работа с WMI из любого языка программирования не вызывает затруднений. Поэтому используйте тот язык написания сценариев, который вам лучше известен и которым вам больше нравится пользоваться.
Листинг 1. VBScript
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_NetworkAdapterConfiguration",,48)
For Each objItem in colItems
Wscript.Echo "-----------------------------------"
Wscript.Echo "Win32_NetworkAdapterConfiguration instance"
Wscript.Echo "-----------------------------------"
If isNull(objItem.IPAddress) Then
Wscript.Echo "IPAddress: "
Else
Wscript.Echo "IPAddress: " & Join(objItem.IPAddress, ",")
End If
Next
Листинг 2. VB.NET
Imports System
Imports System.Management
Imports System.Windows.Forms
Namespace WMISample
Public Class MyWMIQuery
Public Overloads Shared Function Main() As Integer
Try
Dim searcher As New ManagementObjectSearcher( _
"root\CIMV2", _
"SELECT * FROM Win32_NetworkAdapterConfiguration")
For Each queryObj As ManagementObject in searcher.Get()
Console.WriteLine("-----------------------------------")
Console.WriteLine("Win32_NetworkAdapterConfiguration instance")
Console.WriteLine("-----------------------------------")
If queryObj("IPAddress") Is Nothing Then
Console.WriteLine("IPAddress: {0}", queryObj("IPAddress"))
Else
Dim arrIPAddress As String()
arrIPAddress = queryObj("IPAddress")
For Each arrValue As String In arrIPAddress
Console.WriteLine("IPAddress: {0}", arrValue)
Next
End If
Next
Catch err As ManagementException
MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
End Try
End Function
End Class
End Namespace
Листинг 3. C#
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class MyWMIQuery
{
public static void Main()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_NetworkAdapterConfiguration");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_NetworkAdapterConfiguration instance");
Console.WriteLine("-----------------------------------");
if(queryObj["IPAddress"] == null)
Console.WriteLine("IPAddress: {0}", queryObj["IPAddress"]);
else
{
String[] arrIPAddress = (String[])(queryObj["IPAddress"]);
foreach (String arrValue in arrIPAddress)
{
Console.WriteLine("IPAddress: {0}", arrValue);
}
}
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
}
}
Листинг 4. Perl
use strict;
use Win32::OLE('in');
use constant wbemFlagReturnImmediately => 0x10;
use constant wbemFlagForwardOnly => 0x20;
my $computer = ".";
my $objWMIService = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2") or die "WMI connection failed.\n";
my $colItems = $objWMIService->ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
foreach my $objItem (in $colItems) {
print "-----------------------------------"\n";
print "Win32_NetworkAdapterConfiguration instance";
print "-----------------------------------\n";
print "IPAddress: " . join(",", (in $objItem->{IPAddress})) . "\n";
}
Листинг 5. JScript
var wbemFlagReturnImmediately = 0x10;
var wbemFlagForwardOnly = 0x20;
var strComputer = ".";
var objWMIService = GetObject("winmgmts:\\\\" + strComputer + "\\root\\CIMV2");
var colItems = objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
var enumItems = new Enumerator(colItems);
for (; !enumItems.atEnd(); enumItems.moveNext()) {
var objItem = enumItems.item();
WScript.Echo("-----------------------------------");
WScript.Echo("Win32_NetworkAdapterConfiguration instance");
WScript.Echo("-----------------------------------");
try { WScript.Echo("IPAddress: " + (objItem.IPAddress.toArray()).join(",")); }
catch(e) { WScript.Echo("IPAddress: null"); }
}
Листинг 6. WMIC
wmic nicconfig get IPAddress /value
Строим moniker string
Теперь более четко определимся, что такое moniker string? Дословный перевод этого словосочетания мог бы звучать примерно так: строка-прозвище или строка-кличка. По смыслу же это некое специальное имя (ссылка) для обращения к объектам или классам объектов WMI. Формат этой строки фактически представляет собой разновидность URL (Universal Resource Locator). Все moniker string начинаются с отличительного идентификатора Winmgmts:. Эта часть moniker string является обязательной. Далее формат зависит от того, как мы хотим обращаться к объекту.
Например, вот так:
Winmgmts://server01/root/cimv2:Win32_OperatingSystem
В приведенном примере server01 – это, как вы уже догадались, сетевое имя компьютера, на котором мы хотим получить доступ к объекту WMI. Если указать вместо сетевого имени символ «.» (точка), то подключение будет происходить к локальному компьютеру. Root/CIMv2 – это пространство имен репозитория WMI (по аналогии очень похоже на виртуальный каталог веб-сервера). Подробнее пространства имен я опишу чуть ниже. После двоеточия идет наименование класса WMI, к объектам которого мы хотим обратиться. В данном примере это класс Win32_OperatingSystem. Следует заметить, что в moniker string можно использовать не только прямую наклонную черту, но и обратную, так что строки «winmgmts://server01/root/cimv2» и «winmgmts:server01 ootcimv2» одинаковы.
При подключении к репозиторию WMI необязательно указывать имя локального сервера точкой. Строка может выглядеть и так: «WinMgmts:root/CIMv2». Если в строке moniker-string имя сервера не указано, то подключение произойдет и к локальному репозиторию WMI. Точно так же, как и в случае использования строки «WinMgmts://./root/CIMv2».
Пространства имен WMI
Что же такое WMI namespace (пространство имен WMI)? Пространство имен WMI – это раздел (директория) репозитория WMI, которая призвана группировать классы и объекты WMI по назначению, а также определять атрибуты безопасности при доступе к классам и объектам в каждом таком контейнере. Фактически это, как уже отмечалось выше, полная аналогия с директориями на веб-сервере (см. рис. 1). Все пространства имен начинаются с корня, который в WMI обозначается ключевым словом root. После имени корня через косую черту указывается пространство имен. Пространства имен могут быть вложенными. Пример того, как выглядит пространство имен: root/mynamespace/subnamespace. Подавляющее большинство классов и объектов, которые интересуют вас, размещается в пространстве имен root/CIMv2.
Рисунок 1. Дерево пространств имен WMI
Одно из существующих в Windows пространств имен WMI может быть выбрано по умолчанию. Это означает, что если вы попытаетесь подключиться к этому хосту, не указав в moniker-string необходимое пространство имен, то вы автоматически будете подключены к выбранному по умолчанию. В стандартной инсталляции Windows по умолчанию выбрано пространство имен rootcimv2.
Знакомство с WMI Code Creator 1.0
Теперь давайте познакомимся с одной из наиболее удобных и функциональных утилит для системного администратора – WMI Code Creator 1.0 [2]. На мой взгляд, сочетаемый этой утилитой функционал и удобство превосходят все остальные описанные мной ранее утилиты. В упражнении с этой утилитой мы будем решать задачу управления опцией Remote Desktop в свойствах системы, которая позволяет разрешить или запретить удаленные подключения к рабочему столу для задач администрирования. Этот пример будет работать только на ОС Windows XP и новее, а также на Windows 2000 Server с установленными службами терминалов.
Для начала скачайте и распакуйте эту утилиту. Запустите файл WMICodeCreator.exe и выберите в меню «Code Language Visual Basic Script». Затем проверьте в меню «Target Computer», что установлена опция «Local Computer». После этого удостоверьтесь, что у вас открыта закладка «Query for data from WMI class», и на этой закладке выберите класс «Win32_TerminalServiceSetting». В наборе свойств (properties) выделите «AllowTSConnections», как это показано на рис. 2.
Рисунок 2. Окно утилиты WMI Code Creator 1.0 с открытой закладкой Query
Свойство «Win32_TerminalService Setting.AllowTSConnections» определяет состояние опции «Remote Desktop» в свойствах системы. В правом окне вы увидите скрипт, который сгенерировала утилита для того, чтобы вывести на экран выбранное вами свойство. Нажмите кнопку «Search for Property Values». Вы увидите все варианты значений этого свойства для всех экземпляров объектов класса «Win32_TerminalServiceSetting». Нажмите кнопку «Execute Code». Откроется окно командной строки, где будет выведен результат работы скрипта. Если опция «Remote Desktop» включена, то будет отображена 1, в противном случае 0. Проверьте в свойствах вашей системы, что результат работы скрипта совпадает с тем, как установлена опция «Remote Desktop».
Теперь откройте закладку «Execute a method». Снова выберите класс «Win32_TerminalServiceSetting». В списке методов выберите «SetAllowTS Connections», как это показано на рис. 3.
Рисунок 3. Окно утилиты WMI Code Creator 1.0 с открытой закладкой Execute
Затем в списке «Method [in] parameters» установите значение «AllowTSConnections» противоположное от того, что мы получили на предыдущем шаге. Для этого нужно просто кликнуть мышью на входной параметр метода. Нажмите кнопку «Execute Code». Откроется консольное окно, в котором будет выдано значение, возвращенное методом SetAllowTSConnections. Если все прошло удачно – это будет 0. Теперь проверьте, изменилась ли опция «Remote Desktop» в свойствах вашей системы.
Обратите внимание на то, что вы можете очень быстро получить контекстную справку из библиотеки MSDN по выбранному классу WMI, щелкнув мышью по ссылке: «Get Documentation for this class from the online MSDN Library».
Краткий обзор вопросов безопасности WMI
Если внимательно изучить схему архитектуры WMI, которую я приводил в начале статьи, то легко заметить, что все взаимодействие с ядром WMI происходит с использованием интерфейсов COM+/DCOM. В свою очередь COM+ и DCOM в качестве транспортного протокола используют RPC. Эта архитектурная особенность накладывает определенный отпечаток на идеологию системы безопасности WMI. В частности, для людей, знакомых с технологиями DCOM и COM+, слова «имперсонация» и «делегирование» не новы. Однако среди читателей большинство – системные администраторы, а не программисты, поэтому я постараюсь уделить некоторое внимание этим вопросам.
Для того чтобы некая учетная запись имела возможность подключаться к репозиторию WMI, необходимо дать ей соответствующие права. Права, как вы уже могли догадаться, нужно дать как на пространство имен – WMI name space (воспользовавшись оснасткой wmimgmt.msc), так и на DCOM-приложения диспетчера WMI – CIM Object Manager (воспользовавшись оснасткой управления COM+ comexp.msc или утилитой dcomcnfg.exe). Вот минимальный список приложений DCOM, права на которые необходимы для удаленной работы с WMI: Windows Management and Instrumentation, Microsoft WMI Provider Subsystem Host. Некоторые сведения по вопросам настройки прав доступа к WMI и сетевой безопасности вы можете почерпнуть из статьи Microsoft Knowledge Base KB875605 или из библиотеки MSDN [3]. Права на другие DCOM-приложения могут понадобиться в зависимости от используемого режима имперсонации.
Имперсонация
Зачем нужна имперсонация? Все довольно просто, это метод, при котором для подключения к ресурсу процесс (поток) или система должны использовать не свой контекст безопасности, а учетные данные другого субъекта безопасности. Представьте, что некая служба, запущенная в контексте безопасности LocalSystem, должна выполнить действие от лица другой учетной записи (например, от лица текущего зарегистрированного на компьютере пользователя). В этом случае ей необходимо создать специальный маркер доступа (Access Token), описывающий контекст безопасности той учетной записи, под которой мы хотим выполнить указанное действие. Безусловно, для того чтобы создать такой маркер доступа, этой службе необходимо знать учетные данные этого пользователя или, если этот процесс происходит на локальной машине, получить копию маркера доступа зарегистрированного локально пользователя (безусловно, для этого контекст безопасности службы должен обладать привилегией создания маркеров доступа).
Бывает чуть более сложный вариант имперсонации – делегирование. Этот вариант необходим тогда, когда подключение к конечному ресурсу выполняется не самим субъектом безопасности (в нашем примере – службой от лица пользователя), а через посредника (например, промежуточный сервер). Представьте ситуацию, что интернет-пользователь подключается не напрямую к базе данных, а через веб-приложение на третьем сервере. Для осуществления такого подключения веб-приложение должно получить от субъекта безопасности (нашей службы) маркер доступа с правом делегирования – это позволит веб-приложению использовать маркер доступа субъекта безопасности уже при подключении к базе данных.
В случае с WMI делегирование может выглядеть так – мы, работая на станции администратора, подключаемся по WMI к некому серверу и запускаем на нем процесс с помощью метода Execute класса Win32_Process. Теперь представим, что этот процесс есть не что иное, как другой скрипт WMI, который подключается к еще одному хосту в сети для того, чтобы сделать какие-то действия. Если мы не воспользуемся делегированием, то на конечной машине скрипт будет запущен в контексте безопасности учетной записи промежуточного сервера, что далеко не всегда желаемо. С другой стороны, подобная ситуация с делегированием в реальной жизни требуется крайне редко.
В таблице 1 представлены поддерживаемые уровни имперсонации WMI.
Таблица 1. Уровни имперсонации
Уровень имперсонации
|
Описание
|
Anonymous
1
|
Анонимный уровень имперсонации COM, маскирующий учетную запись вызывающего. Вызов WMI с этим уровнем имперсонации может завершиться ошибкой
|
Default
0
|
Уровень имперсонации по умолчанию
|
Delegate
4
|
Уровень имперсонации COM – делегирование. Разрешает использовать другим объектам учетные данные вызывающего субъекта для обращения к третьим объектам. Этот уровень может дать неоправданно высокие привилегии промежуточному объекту. Поддерживается только на Windows 2000 и выше
|
Identify
2
|
Уровень имперсонации COM – идентификация. Позволяет объектам вызова запрашивать учетные данные у вызывающего субъекта. Вызов WMI с этим уровнем имперсонации может завершиться с ошибкой
|
Impersonate
3
|
Уровень имперсонации COM – обычная имперсонация. Позволяет вызываемому объекту использовать учетные данные вызывающего субъекта для совершения только своих действий. Это рекомендуемый уровень имперсонации
|
Аутентификация
Аутентификация, целостность и конфиденциальность являются неотъемлемыми характеристиками безопасного взаимодействия систем по сети. При использовании WMI поддерживаются перечисленные в таблице 2 уровни аутентификации и проверки подлинности. Наиболее часто употребимый уровень – Connect (аутентификация и авторизация при вызове). Однако если вы хотите предотвратить возможное изменение передаваемых данных или их перехват методом men in the middle, то лучшим выбором могут являться режимы Pkt (проверка аутентичности клиента), PktIntegrity (проверка аутентичности клиента и целостности передаваемых данных) и PktPrivacy (проверка аутентичности клиента и шифрование передаваемых данных с проверкой целостности).
Таблица 2. Варианты аутентификации и проверки целостности
Уровень аутентификации
|
Описание
|
Call
Call
3
|
Call-level COM authentication.
Аутентификация в начале каждого вызова объекта WMI
|
Connect
Connect
2
|
Connect-level COM authentication.
Аутентификация только при установлении соединения с сервером WMI. Одни учетные данные используются для всего сеанса взаимодействия
|
Default
Default
0
|
WMI использует настройки аутентификации COM по умолчанию
|
None
None
1
|
Аутентификация COM не используется
|
Packet
Pkt
4
|
Packet-level COM authentication.
Аутентификация всех данных, получаемых от клиента, с подтверждением подлинности отправителя для каждого RPC-пакета
|
PacketIntegrity
PktIntegrity
5
|
Packet Integrity-level COM authentication.
Аутентификация и проверка целостности передаваемых данных для каждого RPC-пакета
|
PacketPrivacy
PktPrivacy
6
|
Packet Privacy-level COM authentication.
Аутентификация, проверка целостности и шифрование данных каждого передаваемого RPC-пакета
|
Привилегии
Администраторам Windows хорошо известны настройки безопасности системы и их раздел «User Right Assignments» (привилегии пользователей), доступные в консоли безопасности системы и групповых политиках домена. Ряд действий с операционной системой можно проделать только при наличии у пользователя или группы, куда он входит, той или иной привилегии. К таким действиям относятся, например, перезагрузка системы (завершение ее работы), восстановление состояния системы из резервной копии или смена системного времени.
Поскольку с использованием WMI можно выполнить все эти действия, разработчики WMI заложили дополнительный механизм защиты. Смысл его в следующем: даже если учетная запись пользователя обладает необходимыми для действия с системой привилегиями, он все равно не сможет выполнить это действие, пока явно не активирует эту привилегию перед выполнением действия. В частности, если администратор запустит скрипт WMI, запрашивающий перезагрузку системы, этого все равно не произойдет, пока в скрипте не будет явно активирована эта привилегия.
Список привилегий и их численных кодов указан в таблице 3.
Таблица 3. Привилегии
Привилегии
|
Описание
|
wbemPrivilegeCreateToken
SeCreateTokenPrivilege
CreateToken
1
0x1
|
Привилегия требуется для создания основного токена безопасности процесса
|
wbemPrivilegePrimaryToken
SeAssignPrimaryTokenPrivilege
AssignPrimaryToken
2
0x2
|
Привилегия требуется для замены (назначения нового) основного токена безопасности процесса
|
wbemPrivilegeLockMemory
SeLockMemoryPrivilege
3
0x3
|
Привилегия требуется для закрепления соответствия между страницами физической памяти и логического адресного пространства
|
wbemPrivilegeIncreaseQuota
SeIncreaseQuotaPrivilege
IncreaseQuotaPrivilege
4
0x4
|
Привилегия требуется для назначения квот процессу
|
wbemPrivilegeMachineAccount
SeMachineAccountPrivilege
MachineAccount
5
0x5
|
Привилегия требуется для создания учетной записи компьютера
|
wbemPrivilegeTcb
SeTcbPrivilege
Tcb
6
0x6
|
Привилегия обозначает ее владельца как часть Trusted Computer Base
|
wbemPrivilegeSecurity
SeSecurityPrivilege
Security
7
0x7
|
Привилегия требуется для выполнения ряда функций, связанных с безопасностью, например просмотр журналов аудита. Привилегия определяет её владельца как Security Operator
|
wbemPrivilegeTakeOwnership
SeTakeOwnershipPrivilege
TakeOwnership
8
0x8
|
Привилегия требуется для получения права владельца объекта на объекты безопасности в отсутствии явных на то разрешений
|
wbemPrivilegeLoadDriver
SeLoadDriverPrivilege
LoadDriver
9
0x9
|
Привилегия требуется для загрузки и выгрузки драйверов устройств
|
wbemPrivilegeSystemProfile
SeSystemProfilePrivilege
SystemProfile
10
0xA
|
Привилегия требуется для сбора профилирующей информации всей системы
|
wbemPrivilegeSystemtime
SeSystemtimePrivilege
Systemtime
11
0xB
|
Привилегия требуется для изменения системного времени
|
wbemPrivilegeProfileSingleProcess
SeProfileSingleProcessPrivilege
ProfileSingleProcess
12
0xC
|
Привилегия требуется для сбора профилирующей информации для одного процесса
|
wbemPrivilegeIncreaseBasePriority
SeIncreaseBasePriorityPrivilege
IncreaseBasePriority
13
0xD
|
Привилегия требуется для увеличения базового проиритета процесса
|
wbemPrivilegeCreatePagefile
SeCreatePagefilePrivilege
CreatePagefile
14
0xE
|
Привилегия требуется для создания и (или) изменения файла подкачки
|
wbemPrivilegeCreatePermanent
SeCreatePermanentPrivilege
CreatePermanent
15
0xF
|
Привилегия требуется для создания постоянного общего объекта
|
wbemPrivilegeBackup
SeBackupPrivilege
Backup
16
0x10
|
Привилегия требуется для выполнения резервного копирования
|
wbemPrivilegeRestore
SeRestorePrivilege
Restore
17
0x11
|
Привилегия требуется для выполнения операции восстановления. Эта привилегия позволяет ее владельцу устанавливать для любого объекта произвольный существующий SID в качестве владельца объекта
|
wbemPrivilegeShutdown
SeShutdownPrivilege
Shutdown
18
0x12
|
Привилегия требуется для перезагрузки и завершения работы ОС
|
wbemPrivilegeDebug
SeDebugPrivilege
Debug
19
0x13
|
Привилегия требуется для отладки процессов
|
wbemPrivilegeAudit
SeAuditPrivilege
Audit
20
0x14
|
Привилегия требуется для записи в журналы аудита
|
wbemPrivilegeSystemEnvironment
SeSystemEnvironmentPrivilege
SystemEnvironment
21
0x15
|
Привилегия требуется для модификации энергонезависимой памяти в тех системах, которые используют ее для хранения своей конфигурации
|
wbemPrivilegeChangeNotify
SeChangeNotifyPrivilege
ChangeNotify
22
0x16
|
Привилегия требуется для получения нотификаций об изменении файлов и директорий. Так же эта привилегия отменяет перекрестную проверку доступа к файлам и папкам. Эта привилегия по умолчанию дана всем пользователям
|
wbemPrivilegeRemoteShutdown
SeRemoteShutdownPrivilege
RemoteShutdown
23
0x17
|
Привилегия требуется для завершения работы ОС по сети
|
wbemPrivilegeUndock
SeUndockPrivilege
Undock
24
0x18
|
Привилегия требуется для снятия компьютера с док-станции
|
wbemPrivilegeSyncAgent
SeSyncAgentPrivilege
SyncAgent
25
0x19
|
Привилегия требуется для вызова процедуры синхронизации службы каталога
|
wbemPrivilegeEnableDelegation
SeEnableDelegationPrivilege
EnableDelegation
26
0x1A
|
Привилегия требуется для доверия пользователям или группам при делегировании
|
wbemPrivilegeManageVolume
SeManageVolumePrivilege
ManageVolume
27
0x1B
|
Привилегия требуется для операций обслуживания дисковых томо
|
Каким образом активировать эти привилегии, показано в примерах из раздела «Подключение к удаленным компьютерам». Важно запомнить, что активировать привилегии нужно до подключения к репозиторию WMI, а не после.
Подключение к удаленным компьютерам
Подключение к другим компьютерам по сети чаще всего вызывает проблемы у тех, кто только начинает осваивать технологию WMI и программирование с ее использованием. Поэтому я считаю необходимым привести примеры кода на VBScript, которые позволяют решать эту задачу, и кратко пояснить их. Единственное, что необходимо запомнить, так это то, что запрещается подключаться к репозиторию WMI на локальном компьютере, используя другую учетную запись (не ту, под которой происходит обращение к CIM Object Manager). Это ограничение обычно решается использованием утилиты RunAs и ей подобных методов.
Вариант подключения с использованием маркера доступа произвольной учетной записи:
strComputer = "server01"
Set objLocator = CreateObject("WbemScripting.SWbemLocator")
objLocator.Security_.AuthenticationLevel = 3
objLocator.Security_.Privileges.Add(18)
Set objWMIService = objLocator.ConnectServer(_
strComputer, "root\cimv2", "mydomain\administrator", "password")
objWMIService.Security_.ImpersonationLevel = 3
Set colItems = objWMIService.ExecQuery(_
"SELECT * FROM Win32_OperatingSystem",,48)
For Each objItem in colItems
Wscript.Echo "-----------------------------------"
Wscript.Echo "Win32_OperatingSystem instance"
Wscript.Echo "-----------------------------------"
Wscript.Echo "Caption: " & objItem.Caption
Wscript.Echo "Name: " & objItem.Name
Rem Первый вариант вызова метода Reboot()
Set objOutParams = objWMIService.ExecMethod(_
"Win32_OperatingSystem.Name='" & CStr(objItem.Name) & "'", "Reboot")
Rem Второй вариант вызова метода Reboot()
objItem.Reboot()
Next
Обратите внимание, что для того, чтобы перезагрузить удаленный компьютер, нам необходимо явно активировать эту привилегию. Кроме того, в этом примере мы используем для подключения к удаленному компьютеру учетные данные отличные от тех, под которыми запущен данный скрипт.
Другой вариант подключения с использованием текущего маркера доступа и moniker string:
strComputer = "server01"
Set objWMIService = GetObject(_
"WinMgmts:{impersonationLevel=Impersonate, authenticationLevel=Call, (Shutdown)}!//" & strComputer & "/root/cimv2")
Set colItems = objWMIService.ExecQuery(_
"SELECT * FROM Win32_OperatingSystem",,48)
For Each objItem in colItems
Wscript.Echo "-----------------------------------"
Wscript.Echo "Win32_OperatingSystem instance"
Wscript.Echo "-----------------------------------"
Wscript.Echo "Caption: " & objItem.Caption
Wscript.Echo "Name: " & objItem.Name
Rem Первый вариант вызова метода Reboot()
Set objOutParams = objWMIService.ExecMethod(_
"Win32_OperatingSystem.Name='" & CStr(objItem.Name) & "'", "Reboot")
Rem Второй вариант вызова метода Reboot()
objItem.Reboot()
Next
В данном примере мы познакомились с еще одной возможностью, заложенной в moniker string. Мы можем включать в строку moniker string в фигурных скобках «{ }» параметры имперсонации, аутентификации и набор используемых привилегий. Таким образом, полный формат moniker string можно было бы записать так:
Winmgmts:{ <security settings>, (<privileges>) }!//<server>/<namespace>:<Class | Object>
Есть и еще не описанные мной поля в формате moniker string, но поскольку они довольно редко нужны на практике, то я рекомендую желающим ознакомиться с ними по оригинальной документации на сайте Microsoft [3] самостоятельно.
События WMI и уведомляющие запросы
События WMI – это очень удобный и эффективный механизм выявления изменений в системе и экземплярах объектов WMI. Представьте, что вы хотите написать скрипт, который будет реагировать на какое-либо системное событие. Например, на запуск процесса или на перезагрузку системы или, скажем, на изменение конфигурации сетевого интерфейса. Если бы не было событий WMI, вам бы пришлось написать скрипт, который опрашивал бы состояние интересующего вас свойства определенного экземпляра объекта WMI. Вам бы пришлось запускать такой скрипт с определенной периодичностью и сравнивать полученные значения – согласитесь, в этом много бестолкового труда и излишней траты системных ресурсов. Есть гораздо более эффективное решение этого вопроса. И, как вы уже догадались, – это события WMI и уведомляющие запросы.
Обработка событий может быть синхронной и асинхронной. Синхронная обработка событий – это когда процесс ожидает события и более ничем не занят. Обычно это ожидание – бесконечный цикл проверки условия: поступило событие или нет. Асинхронная обработка подразумевает, что процесс регистрирует обработчик события (подписывается на событие) и далее продолжает выполнять различные задачи. Когда событие возникает, нормальная работа процесса прерывается, запоминается место, где произошло прерывание, а управление передается на зарегистрированный обработчик событий. После обработки события обработчиком, управление возвращается на то действие основного процесса, которое было прервано.
Оба приведенных ниже скрипта отслеживают запуск процесса с именем cmd.exe. Однако между ними все же есть различие.
Приведенный ниже скрипт (первый из двух) использует синхронную технику уведомляющего запроса для создания экземпляра объекта Win32_ProcessStartTrace, который отвечает за отслеживание событий запуска процессов о системе. Каждый раз, когда в системе порождается процесс с именем cmd.exe, метод NextEvent возвращает управление скрипту.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = 'cmd.exe'")
Wscript.Echo "Waiting for events ..."
Do While(True)
Set objReceivedEvent = objEvents.NextEvent
Wscript.Echo "CMD.EXE started"
Loop
Второй скрипт, который приведен ниже, использует немного другую синхронную технику. Этот метод более универсальный, так как не завязан на специальный класс WMI Win32_ProcessStartTrace. С помощью уведомляющего запроса отслеживается состояние всего пула объектов класса Win32_Process. Каждый раз, когда в системе порождается новый экземпляр объекта, принадлежащего классу Win32_Process и полем Description, содержащим строку cmd.exe, метод NextEvent возвращает управление скрипту.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE (TargetInstance ISA 'Win32_Process') AND (TargetInstance.Description = 'cmd.exe')")
Wscript.Echo "Waiting for events ..."
Do While(True)
Set objReceivedEvent = objEvents.NextEvent
Wscript.Echo "CMD.EXE started"
Loop
Следует отметить, что скрипты WSH и ядро WMI помимо синхронного ожидания событий позволяют асинхронно обрабатывать события и исключения. Вы можете не отдавать управления из скрипта менеджеру событий WMI и продолжать выполнение необходимых действий. В то же время, когда возникнет отслеживаемое вами событие, управление будет передано на специальную подпрограмму скрипта, и будут выполнены необходимые действия. Это работает так же, как прерывания или события форм в Visual Basic или Visual Basic for Application.
Использование техники регистрации асинхронных событий и их обработки требует детального изложения материала и не умещается в рамки этой статьи. Возможно, этот материал появится в виде отдельной статьи. Намекну лишь, что WMI Code Creator 1.0 позволяет легко создавать скрипты для асинхронной обработки событий WMI.
Есть еще один, принципиально иной способ обработки событий с использованием WMI. С помощью создания экземпляров объектов специальных классов (классов с общим названием Standard Event Consumers) отслеживать события и выполнять несколько типовых действий (отправка уведомления по SMTP, запись в журнал событий, запись в текстовый файл, запуск приложения, запуск скрипта) вообще без написания скриптов WSH. Однако об этом методе мы поговорим в другой раз.
Продукты, использующие WMI
После знакомства с технологией WMI у читателей может возникнуть желание начать разрабатывать собственные скрипты и системы управления и мониторинга. Безусловно, это похвальное желание, но, возможно, не стоит поступать столь опрометчиво. Возможно, стоит оглянуться по сторонам и обнаружить, что уже многое сделано в этом направлении другими людьми и их решения успешно развиваются. Для начала советую заглянуть в подборку скриптов в TechNet Script Center [4, 5]. Если все же вы не горите желанием объединять разрозненные скрипты в единую систему управления и мониторинга и фактически изобретать велосипед, советую вам обратить внимание на продукты Microsoft SMS 2003 (http://www.microsoft.com/smserver) и Microsoft Operations Manager 2005 (http://www.microsoft.com/mom).
SMS 2003 SP1
Система управления изменениями и конфигурациями, построенная на базе Microsoft Systems Management Server 2003, представляет собой клиент-серверное распределенное приложение. Клиентская часть устанавливается на управляемые рабочие станции и серверы и периодически запрашивает с сервера, входящего в состав системы SMS 2003, задания, которые затем выполняются на клиентской части ПО SMS 2003. Эти задания касаются как самих настроек клиентской части, так и собственно задач, которые решает система SMS 2003. Основными задачами в сетях на базе продуктов Microsoft, решаемыми системой управления на базе SMS 2003, являются:
- автоматизация процесса установки клиентской части системы SMS 2003 на рабочие станции;
- инвентаризация аппаратного обеспечения рабочих станций;
- инвентаризация программного обеспечения рабочих станций;
- инвентаризация установленных и пропущенных обновлений системного ПО;
- группировка рабочих станций на основании данных инвентаризации в коллекции;
- установка программного обеспечения на группы компьютеров (коллекции);
- установка операционных систем из образов на новые компьютеры и переустановка с сохранением профилей пользователей на эксплуатируемых компьютерах;
- установка необходимых обновлений безопасности;
- выполнение на клиентских рабочих станциях задач обслуживания, оформленных в виде скриптов и/или исполняемых файлов;
- управление мобильными устройствами PocketPC;
- определение частоты запуска указанных приложений;
- отслеживание соответствия набора и версий программного обеспечения на рабочих станциях заданным параметрам;
- формирование отчетов о рабочих станциях и серверах;
- формирование отчетов о состоянии и работе самой системы;
- оптимизация нагрузки на сеть при передаче дистрибутивов и установке ПО на рабочие станции и серверы;
- удаленная поддержка пользователей с использованием Remote Tools, в состав которых входят: удаленное управление рабочим столом АРМ, передача файлов, удаленная перезагрузка, интерактивное общение администратора с пользователем и удаленная командная консоль;
- обеспечение контроля доступа ко всем функциям и объектам системы управления на базе SMS 2003 для авторизованных пользователей.
Все эти функции SMS 2003 реализованы с использованием технологии WMI. В частности, весь процесс инвентаризации, который производит агент SMS, представляет собой набор WMI-запросов.
Все свои настройки и задания (Advertisements), а также некоторые промежуточные результаты инвентаризации агент SMS также хранит в репозитории WMI в отдельном пространстве имен: rootCCM.
MOM 2005 SP1
Система мониторинга на базе Microsoft Operations Manager 2005 позволяет решать следующие задачи:
- обеспечение непрерывного наблюдения в реальном времени за состоянием ИС компании и автоматическая регистрация инцидентов;
- снижение времени, требуемого для оповещения дежурной смены группы мониторинга об изменениях и сбоях, происходящих в ИС компании;
- снижение количества незарегистрированных инцидентов;
- обеспечение мониторинга всех компонентов ИС компании и распределенное по всем сегментам сети наблюдение за их состоянием;
- предоставление кратких рекомендаций администраторам системы по большинству событий, регистрируемых системой мониторинга;
- обеспечение отказоустойчивости системы мониторинга;
- обеспечение возможности разделения административных полномочий на участки системы мониторинга;
- возможность ведения корпоративной базы знаний по инцидентам;
- выявление взаимосвязей между возникающими инцидентами и источниками проблем.
Система мониторинга представляет собой клиент-серверное распределенное приложение. На целевые серверы (те серверы прикладных систем, на которых осуществляется мониторинг) устанавливается специальное программное обеспечение – агент системы мониторинга MOM 2005. Агенты системы мониторинга получают свои настройки и правила (политики) мониторинга с управляющих серверов.
Для каждого сервера, за которым ведет наблюдение его агент, в зависимости от установленного на него программного обеспечения применяется свой набор правил мониторинга. Правила мониторинга объединяются в группы правил, которые применяются к группам компьютеров. Группы компьютеров содержат целевые системы мониторинга, которые туда добавляются либо автоматически на основании данных из реестра целевых систем, либо вручную.
Множество правил мониторинга, которые использует MOM 2005, представляют собой скрипты, использующие WMI для получения и обработки данных о системе и ее компонентах.
Что же дальше?
«Ну, хорошо, – скажете вы. – Я прочитал эту статью, но что мне это даст. Автор рассуждает о WMI, но у меня конкретные проблемы, решение которых я ищу, и чем конкретно мне в моих проблемах поможет WMI?» Да, пожалуй, этот вопрос заботит любого системного администратора, когда ему приходится столкнуться с новой технологией и встать перед выбором использовать ее или нет.
Я надеюсь, что этот вопрос возникнет лишь у небольшого числа читателей, поскольку я постарался отразить в этой статье значимость и пользу технологии WMI, а так же разобрать самые скользкие и сложные вопросы, возникающие при ее использовании. Но все же я отвечу и тем, у кого этот вопрос все-таки возник. Уважаемые коллеги, WMI – это открытая технология, основанная на открытых стандартах, которая использует все больше и больше программных продуктов различных производителей. Она позволяет сэкономить вам свое рабочее время и решать поистине сложные задачи простым способом. Стандарт WBEM, на котором основан WMI, реализован на UNIX и Linux системах [6] и позволяет вам развивать гибкую и кроссплатформенную систему управления и мониторинга сетью.
Вы можете пойти двумя путями – либо приобрести готовый продукт управления и мониторинга (практически все из них совместимы с WBEM и WMI), а можете создать свое средство, но в обоих случаях знания по WMI вам обязательно пригодятся.
Ко всему выше сказанному следует добавить еще то, что Windows XP и Windows Server 2003 поддерживают в групповых политиках домена Active Directory технологию WMI Query Filtering. Что это такое? Это средство, которое позволяет определять, какие групповые политики следует применять к каким рабочим станциям и пользователям на основе результатов запросов WQL к WMI на том компьютере, на котором должно выполняться применение этой политики. В частности, в сочетании с Software Distribution Policy вы можете сделать так, чтобы офисный пакет Office 2003 мог устанавливаться только на те машины, которые имеют определенный объем ОЗУ и свободного пространства на жестком диске. Или, скажем, устанавливать очередной Service Pack через групповую политику только на те машины, у которых на жестком диске имеется не менее 2 Гб свободного пространства. И все это делается одной простой строкой WQL-запроса:
Select * from Win32_LogicalDisk where FreeSpace > 2147483648
Теперь заглянем немного в ближайшее будущее. В области управления системами Windows Server Systems компания Microsoft активно развивает свою новую инициативу – новый командный интерпретатор под кодовым названием MONAD [7]. Это очень гибкий и удобный интерпретатор команд, который будет встроен в следующую версию Microsoft Exchange E12 и Longhorn Server, а также он может быть установлен на любую ОС, поддерживающую .NET Framework 2.0 (Windows 98, Windows 2000, Windows XP, Windows Server 2003). В основе большинства элементов синтаксиса и некоторых принципов работы с MONAD лежат удачные наработки, полученные при разработке WMI и WMIC. Консоль управления MMC 3.0 также будет полностью поддерживать архитектуру MONAD, и множество функций управления, доступные из консоли, будут не чем иным, как скриптами MONAD.
Со временем предполагается, что интерфейсы управления MONAD будут встроены во все продукты компании Microsoft, и, как вы понимаете, навыки, полученные при работе с WMI и WMIC, будут очень полезны всем системным администраторам, работающим с Windows.
Ссылки и литература:
- Леонтьев К. Вы всё ещё не используете WMI? Часть1. – Журнал «Системный администратор», №1, январь 2006 г. – 4-11 с (http://www.samag.ru/cgi-bin/go.pl?q=articles;n=01.2006;a=02).
- WMI Code Creator 1.0 – http://download.microsoft.com/download/0/c/a/0ca7691c-6335-4143-8f9f-6708969f8212/WMICodeCreator.zip.
- Windows Management Instrumentation – http://msdn.microsoft.com/library/en-us/dnanchor/html/anch_wmi.asp.
- TechNet Script Center – http://www.microsoft.com/technet/scriptcenter/default.mspx.
- Portable Script Center – http://www.microsoft.com/downloads/details.aspx?FamilyID=b4cb2678-dafb-4e30-b2da-b8814fe2da5a&DisplayLang=en.
- Проект OpenWBEM – http://www.openwbem.org.
- Microsoft Shell (MSH) – MONAD beta 3 – http://www.microsoft.com/downloads/details.aspx?FamilyID=e8e5203a-574c-4105-af6b-b2fef39adf55&DisplayLang=en.