Для начала что такое WMI (Windows Management Instrumentation)? Это технология, которая с помощью единого интерфейса позволяет управлять компонентами как локальной, так и удаленной операционной системы.
Данный материал рассчитан на тех, кто что-то слышал о WMI, но не знает с чего начать его «ковырять». А так же на тех, кто и не подозревал о существовании такого удобного инструмента.
Я не буду рассказывать о том, как работает, как устроена данная технология, если возникнет интерес — информацию всегда можно найти в MSDN. Моя цель — помочь обеспечить быстрый старт, для тех, кто хочет начать использовать данную технологию.
Что дает применение WMI на практике? Возможность изменять различные параметры операционной системы, управлять общими ресурсами, запрашивать информацию об установленных устройствах, запущенных процессах и т.д.
Кому может пригодиться WMI? Я думаю всем. Вы можете использовать возможности WMI не только из Ваших программ на C#, C++ и других языках программирования, но и создавать собственные скрипты, автоматизирующие процесс сбора информации, изменения конфигурации локальной или удаленной машины.
Для быстрого ознакомления с возможностями WMI можно скачать утилиту WMI Code Creator (размер 122 KB, в архиве сама утилита и исходник на C#) с сайта компании Microsoft. Данная утилита позволяет просматривать пространства имен WMI, классы каждого пространства имен, свойства и методы каждого класса. Плюс она генерирует C#, Visual Basic .NET, Visual Basic Script код.
Чтобы долго не занудствовать я приведу пример получения информации об установленном процессоре. В списке Namespaces (пространство имен) выбираем root\CIMV2, в списке Classes (классы) выбираем Win32_Processor. В списке Results (в нем перечислены свойства класса) выбираем Name и нажимаем Execute Code. В появившемся окне видим название (или названия) установленного процессора.
Другой пример — выведем список расшаренных ресурсов. В этот раз выберем класс Win32_Share, в списке свойств выберем Name затем Execute Code. Получили список ресурсов.
Давайте теперь закроем доступ к какому-нибудь ресурсу, в моем случае это Temp. Переходим на закладку Execute a Method в списке классов выбираем все тот же Win32_Share, в списке Methods (методы класса) выбираем Delete, выбираем папку Temp, Execute Code, если все прошло успешно, то папка Temp более не числится в списке общих ресурсов.
Если Вам не хватает возможностей WMI — Вы всегда можете создать собственный класс. Пример создания такого класса уже публиковался на Хабре.
На этом все, желаю удачи в освоении и применении данной технологии.
- Что такое WMI
- Классы, события и безопасность WMI
- Средства работы с WMI
- Язык запросов WMI
- Использование WMI в сценариях
- Подключение к WMI
- Подключение методом локатора
- Подключение методом моникера
- Использование объекта репозитория
- Асинхронное использование объектов репозитория
- Работа с объектами и коллекциями объектов, полученных в результате запросов
- Примеры сценариев на VBScript
- Использование WMI в программах
- Пример программы на VB.NET
- Использование специальных средств для написания запросов
- Scriptomatic
- WMI Code Creator
- Заключение
Windows Management Instrumentation (WMI) в дословном переводе — это инструментарий управления Windows. Если говорить более развернуто, то WMI — это одна из базовых технологий для централизованного управления и слежения за работой различных частей компьютерной инфраструктуры под управлением платформы Windows. Технология WMI — это расширенная и адаптированная под Windows реализация стандарта WBEM, принятого многими компаниями, в основе которого лежит идея создания универсального интерфейса мониторинга и управления различными системами и компонентами распределенной информационной среды предприятия с использованием объектно-ориентированных идеологий и протоколов HTML и XML.
В основе структуры данных в WBEM лежит Common Information Model (CIM), реализующая объектно-ориентированный подход к представлению компонентов системы. CIM является расширяемой моделью, что позволяет программам, системам и драйверам добавлять в нее свои классы, объекты, методы и свойства.
WMI, основанный на CIM, также является открытой унифицированной системой интерфейсов доступа к любым параметрам операционной системы, устройствам и приложениям, которые функционируют в ней.
Важной особенностью WMI является то, что хранящиеся в нем объекты соответствуют динамическим ресурсам, то есть параметры этих ресурсов постоянно меняются, поэтому параметры таких объектов не хранятся постоянно, а создаются по запросу потребителя данных. Хранилище свойств объектов WMI называется репозиторием и расположено в системной папке операционной системы Windows:
%SystemRoot%\System32\WBEM\Repository\FS
Так как WMI построен по объектно-ориентированному принципу, то все данные операционной системы представлены в виде объектов и их свойств и методов.
Все классы группируются в пространства имен, которые иерархически упорядочены и логически связаны друг с другом по определенной технологии или области управления. В WMI имеется одно корневое пространство имен Root, которое в свою очередь имеет 4 подпространства: CIMv2, Default, Secutiry и WMI.
Классы имеют свойства и методы и находятся в иерархической зависимости друг от друга, то есть классы-потомки могут наследовать или переопределять свойства классов-родителей, а также добавлять свои свойства.
Свойства классов используются для однозначной идентификации экземпляра класса и для описания состояния используемого ресурса. Обычно все свойства классов доступны только для чтения, хотя некоторые из них можно модифицировать определенным методом. Методы классов позволяют выполнить действия над управляемым ресурсом.
Каждому экземпляру класса можно обратиться по полному пути, который имеет следующую структуру:
[\\ComputerName\NameSpace][:ClassName][.KeyProperty1=Value1][,KeyProperty2=Value2]…] где ComputerName - имя компьютера NameSpace - название пространства имен ClassName - имя класса KeyProperty1=Value1, KeyProperty2=Value2 - свойства объекта и значения, по которым он идентифицируется.
Пример обращения к процессу с именем «Calc.exe», который запущен на локальной машине:
\\.\CIMv2:Win32_Process.Name="Calc.exe"
Экземпляры классов могут генерировать события, к которым можно подписываться. При наступлении события WMI автоматически создает экземпляр того класса, которому соответствует это событие. Такой механизм удобно использовать для выполнения определенной команды при наступлении определенного события, то есть следить за состоянием объектов операционной системы.
Общая безопасность в WMI реализуется на уровне операционной системы, а дополнительная политика безопасности основана на уровнях пространств имен и протокола DCOM. То есть если пользователь не имеет права делать какое-то действие через операционную систему, он не сможет это сделать и через WMI. Если же пользователю дано какое-то право в операционной системе, то это еще не означает, что это право будет и в WMI, так как в WMI действуют дополнительные параметры безопасности на уровне пространств имен.
Каждый объект операционной системы имеет свое описание безопасности (SD) со своим списком доступа (ACL), в котором перечислены идентификаторы пользователей (SID) и их привилегии. Каждое пространство имен может иметь собственное SD со своим ACL, где пользователям могут быть назначены разрешения на чтение данных, выполнение методов, запись классов и данных и другие. Данные о дополнительных разрешениях хранятся в репозитории WMI. Отдельные классы из пространств имен не имеют собственных описаний безопасности, они наследуют их от своего пространства имен.
По умолчанию администратор компьютера имеет полные права на использование WMI, а остальные пользователи могут лишь вызывать методы, считывать данные и записывать в репозиторий экземпляры классов провайдеров WMI.
Для доступа к инфраструктуре WMI используется протокол DCOM, через который пользователь подключается к WMI. Чтобы определить, какие права будут у подключившегося пользователя, используется механизмы олицетворения и аутентификации протокола DCOM.
Уровни олицетворения могут принимать следующие значения:
Anonymous | Анонимный | WMI-объект не может получить информацию о пользователе — доступ по такому типу не предоставляется |
Identify | Идентификация | WMI-объект запрашивает маркер доступа пользователя — доступ предоставляется только локально |
Impersonate | Олицетворение | WMI-объект имеет такие же права, какие имеет пользователь — рекомендуемый уровень для выполнения команд на удаленном компьютере |
Delegate | Делегирование | WMI-объект может обратиться от имени пользователя к другому WMI-объекту — нерекомендуемый уровень, так как команды можно выполнять удаленно через цепочку из нескольких компьютеров |
Уровни аутентификации (подлинности) могут принимать следующие значения:
None | Отсутствует | Проверка подлинности отсутствует |
Default | По умолчанию | Стандартные настройки безопасности, которые задаются компьютером-целью команды |
Connect | Подключение | Проверка только во время подключения к компьютеру-цели команды, проверка в ходе работы отсутствует |
Call | Вызов | Проверка подлинности при каждом запросе к компьютеру-цели команды, заголовки пакетов подписываются, но содержимое не шифруется |
Pkt | Пакет | Проверка подлинности всех пакетов к компьютеру-цели команды, заголовки пакетов подписываются, но содержимое не шифруется |
PktIntegrity | Целостность пакета | Проверка подлинности и целостности всех пакетов к компьютеру-цели команды, заголовки пакетов подписываются, но содержимое не шифруется |
PktPrivacy | Секретность пакета | Проверка подлинности и целостности всех пакетов к компьютеру-цели команды, заголовки и содержимое пакетов подписываются и шифруются |
wmimgmt.msc — оснастка консоли управления MMC для настройки WMI на локальном компьютере.
Оснастка консоли управления MMC для настройки WMI
winmgmt.exe — консольная утилита управления WMI локального компьютера.
Консольная утилита управления WMI
wbemtest.exe — графическая утилита для взаимодействия со структурой WMI на локальном или удаленном компьютере.
Графическая утилита для взаимодействия со структурой WMI
wmic.exe — консольная утилита для взаимодействия со структурой WMI на локальном компьютере.
Консольная утилита для взаимодействия со структурой WMI
mofcomp.exe — компилятор MOF-файлов для расширения структуры WMI, управления библиотекой классов WMI и восстановления репозитория.
Компилятор MOF-файлов для расширения структуры WMI
Для обращения к объектам WMI используется специфический язык запросов WMI Query Language (WQL), который является одним из разновидностей SQL. Основное его отличие от ANSI SQL — это невозможность изменения данных, то есть с помощью WQL возможна лишь выборка данных с помощью команды SELECT. Помимо ограничений на работу с объектами, WQL не поддерживает такие операторы как DISTINCT, JOIN, ORDER, GROUP, математические функции. Конструкции IS и NOT IS применяются только в сочетании с константой NULL.
Запросы WQL обычно применяются в скриптах, но их также можно протестировать в программе Wbemtest и в консольной утилите Wmic (утилита wmic не требует написания ключевого слова SELECT и полей выборки)
Общий синтаксис запроса WQL выглядит так:
SELECT свойства FROM имя_класса WHERE свойство оператор значение
Например:
' Выбрать все значения класса Win32_Product и вывести все его свойства SELECT * FROM Win32_Product ' Выбрать все значения класса Win32_Product и вывести свойство Version SELECT Version FROM Win32_Product ' Выбрать значения класса Win32_Product, где свойство Description равно ' "Microsoft Office", и вывести свойство Version SELECT Version FROM Win32_Product WHERE Description = "Microsoft Office"
Как видно из примеров, оператор FROM — это источник (класс), коллекцию экземпляров которого нужно получить, а оператор WHERE — это фильтр в запросе.
В скриптах для подключения к WMI используются два метода: с использованием локатора (SWbemLocator) и с использованием моникера (WinMgmts). Метод локатора позволяет установить соединие с пространством имен от имени определенной учетной записи. Метод моникера разрешает подключаться к WMI только от имени текущей учетной записи.
Использование этого метода необходимо, когда в сценарии нужно явно задать имя и пароль учетной записи для подключения к WMI. Объект SWbemLocator создается так:
Set mSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Подключение к репозиторию WMI производится с помощью метода ConnectServer:
mSWbemServices = mSWbemLocator.ConnectServer([ServerName], [NameSpace], [User], _ [Password], [Locate], [Authority], [SecurityFlags], [WbemNamedValueSet]) где ServerName - имя компьютера (если не указано, то локальный компьютер), NameSpace - пространство имен (если не указано, то пространство по умолчанию), User - имя пользователя в формате Домен\УчетнаяЗапись (если не указано, то текущий пользователь), Password - пароль указанного пользователя, Locate - код локализации (если не указано, то текущий язык), Authority - имя домена, если он не указан в параметре User (если не указано, то текущий домен), SecurityFlags - время ожидания подключения, WbemNamedValueSet - контекстная информация для провайдера, который используется для запроса.
Безопасность объекта указывается с помощью свойства Security_, в котором указывается уровень олицетворения и привилегии.
Пример использования локатора:
' Создание объекта Set mSWbemLocator = CreateObject("WbemScripting.SWbemLocator") ' Задание уровня аутентификации (6 - секретность пакетов) mSWbemLocator.Security_.AuthenticationLevel = 6 ' Задание уровня олицетворения (3 - олицетворение) mSWbemLocator.Security_.ImpersonationLevel = 3 ' Добавление привелегии (разрешение завершать работу) mSWbemLocator.Security_.Privileges.AddAsString("SeShutdownPrivilege") ' Подключение к репозиторию Set mSWbemServices = mSWbemLocator.ConnectServer(".", "Root\CIMv2",,,,, 128)
Моникер — это строка, задающая путь к классу WMI, экземпляр которого должен быть создан. Моникер состоит из обязательного префикса «winmgmts:», необязательных настроек безопасности, необязательного пути к требуемому классу:
Set mSWbemServices = GetObject("winmgmts:[{SecurityOptions}!]\\[Server]\[NameSpace]")
Пример использования моникера:
' Подключение к пространству имен по умолчанию локального компьютера Set mSWbemServices0 = GetObject("winmgmts:") ' Подключение к указанному пространству имен удаленного компьютера ' с указанием метода олицетворения Set mSWbemServices1 = GetObject("winmgmts:{impersonationLevel=Impersonate}!" & _ "\\MyComputer\Root\CIMv2") ' Подключение к указанному объекту локального компьютера ' с указанием метода олицетворения и привилегий Set mSWbemServices2 = GetObject("winmgmts:" & _ "{impersonationLevel=Impersonate, (Shutdown, RemoteShutdown)}!" & _ "\\.\Root\CIMv2:Win32Process.Handle=4") ' Подключение к указанному объекту локального компьютера Set mSWbemServices3 = GetObject("winmgmts:\\.\Root\CIMv2:Win32Process.Handle=4")
В результате подключения к WMI получается объект SWbemServices, который обладает определенными свойствами и методами. Наиболее часто используемые из них — это Get, ExecQuery, ExecMethod.
Метод Get используется для возвращения определения класса или экземпляра управляемого ресурса:
Set mObject = Get([ObjectPath],[Flags],[WbemNamedValueSet]) где ObjectPath - путь к объекту WMI, Flags - опции, WbemNamedValueSet - контекстная информация для провайдера.
Пример использования метода Get:
' Подключение к пространству имен Set mSWbemServices = GetObject("winmgmts:\\.\Root\CIMv2") ' Получение экземпляра класса с заданным свойством Set mProcess = mSWbemServices.Get("Win32_Process.Handle=4")
Метод ExecQuery используется для выполнения запросов на языке WQL:
Set mObject = ExecQuery(Query,[QueryLanguage],[Flags],[WbemNamedValueSet]) где Query - текст запроса, QueryLanguage - язык запроса (всегда равен "WQL") Flags - опции, WbemNamedValueSet - контекстная информация для провайдера.
Пример использования метода ExecQuery:
' Подключение к пространству имен Set mSWbemServices = GetObject("winmgmts:\\.\Root\CIMv2") ' Получение всех экземпляров класса с заданным свойством Set mProcesses = mSWbemServices.ExecQuery("SELECT * FROM Win32_Process WHERE Handle = 4")
Метод ExecMethod используется для выполнения метода указанного объекта:
Set mObject = ExecMethod(ObjectPath, MethodName,[InParams],[Flags],[WbemNamedValueSet]) где ObjectPath - путь к объекту WMI, MethodName - имя метода, InParams - входные параметры для метода, Flags - опции (всегда равно нулю), WbemNamedValueSet - контекстная информация для провайдера.
Пример использования метода ExecMethod:
' Подключение к пространству имен Set mSWbemServices = GetObject("winmgmts:\\.\Root\CIMv2") ' Получение указателя на класс Set mProcess = mSWbemServices.Get("Win32_Process") ' Создание коллекции входных параметров для метода Set mInParams = mProcess.Methods_("Create").InParameters.SpawnInstance_ mInParams.CommandLine = "notepad.exe" ' Выполнение метода Set mOutParams = mSWbemServices.ExexMethod("Win32_Process", "Create", mInParams)
Указанные выше методы работают в синхронном и полусинхронном режиме, то есть программа или сценарий не выполняет следующую команду или запрос до тех пор, пока не получит ответ от текущего запущенного метода.
Аналогично синхронным методам WMI позволяет выполнять команды асинхронно, то есть не дожидаться результатов выполнения очередного запроса и продолжать работу сценария или программы. Названия таких асинхронных методов имеют окончание «Async», а работа с ними почти не отличается от обычных методов, но должны быть использованы два обязательных параметра: ссылка на специальный объект «слив событий» и контекстная информация объекта.
Объект «слива событий» (от английского «sink» — раковина) создается следующим образом:
Set mSink = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_") где Sink_ - префикс для функций.
Наиболее часто используемые события, обрабатываемые таким «сливом» асинхронных методов, — это OnObjectReady и OnCompleted. Как можно догадаться из названий событий, первое происходит, когда возвращается очередной объект, порожденный асинхронным запросом. Второе происходит после полного завершения асихронного метода. Событие OnObjectReady выдает на выход объект, который был запрошен асихронной операцией, а событие OnCompleted — код ошибки или 0.
Пример использования асинхронного метода:
' Подключение к пространству имен Set mSWbemServices = GetObject("winmgmts:\\.\Root\CIMv2") ' Создание объекта "слива событий" Set mSink = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_") ' Флаг завершения асинхронного метода mCompleted = False ' Вызов асинхрнонного запроса mSWbemServices.ExecQueryAsync mSink, "SELECT * FROM Win32_Process" ' Зацикливание скрипта до окончание запроса (здесь можно выполнять любые другие операции) ' Как только асинхронный метод вернет какое-нибудь событие, то будет вызвана ' соотвествующая процедура, которая описана ниже, а работа основного скрипта на время ' прервется While Not mCompleted WScript.Sleep 1000 Wend ' Процедура обработки события возврата очередного объекта Sub Sink_OnObjectReady(mWbemObject, mWbemAsyncContext) WScript.Echo mWbemObject.Name End Sub ' Процедура обработки события завершения запроса Sub Sink_OnCompleted(mResult, mWbemErrorObject, mWbemAsyncContext) If mResult = 0 Then WScript.Echo "Запрос успешно завершен" Else WScript.Echo "Запрос завершен с ошибкой" End If mCompleted = True End Sub
Рассмотренные выше методы возвращают объекты и коллекции объектов, которые обладают своими методами и свойствами. Информацию о всех свойствах и методах, поддерживаемых конкретным объектом, можно получить с помощью такого скрипта:
' Объект mObject получен методом Get ' Получение свойств и их значений For Each mCurrentProperty in mObject.Properties_ Wscript.Echo mCurrentProperty.Name & ": " & mCurrentProperty.Value Next ' Получение методов For Each mCurrentMethod in mObject.Methods_ Wscript.Echo mCurrentMethod.Name Next
Коллекция объектов всегда обладает общими для всех экземпляров свойствами, наиболее часто используемые свойства — это Count и Item.
Count — это свойство коллекции объекта, которое содержит количество элементов коллекции.
Item(mObjectPath) — это метод, который возвращает один объект коллекции, соответствующий указанному пути.
Как уже выяснилось, объект имеет свои методы и свойства, которые соответствуют классу данного экземпляра, но помимо классовых свойств и методов всем объектам присущи универсальные, которые оканчиваются на символ подчеркивания, чтобы отличать их от классовых. Наиболее часто используемые универсальные методы — это ExecMethod_ и Put_.
ExecMethod_(mMethod, mWbemInParamsm, mFlags, mWbemNamedValueSet) — это метод для исполнения классового метода у используемого объекта.
Put_(mFlags, mWbemNamedValueSet) — это метод для записи измененных свойств объекта в репозиторий WMI и в реальный объект.
Пример использования метода Put_ — изменение метки диска:
' Подключение к пространству имен Set mSWbemServices = GetObject("winmgmts:\\.\Root\CIMv2") ' Получение объекта логического диска Set mDisks = mSWbemServices.ExecQuery("SELECT * FROM Win32_LogicalDisk WHERE DeviceID = 'C:'") ' Перебор коллекции возвращенных объектов For Each mDisk in mDisks ' Смена метки диска oDisk.VolumeName = "System" ' Запись изменений oDisk.Put_ Next
Пример использование класса CIM_DataFile для переименования файлов:
' Целевой компьютер mComputer = "." ' Целевая папка mFolderPath = "C:\Temp" ' Подключение к пространству имен целевого компьютера Set mSWbemServices = GetObject("winmgmts:\\" & mComputer & "\Root\CIMv2") ' Получение колекции файлов целевой папки Set mFileList = mSWbemServices.ExecQuery ("ASSOCIATORS OF {Win32_Directory.Name='" _ & mFolderPath & "'} WHERE ResultClass = CIM_DataFile") ' Обработка коллекции файлов For Each mCurrentFile In mFileList ' Формирование нового имени файла mNewName = mCurrentFile.Drive & mCurrentFile.Path & mCurrentFile.FileName _ & "." & mCurrentFile.Extension & ".old" ' Переименование файла errResult = mCurrentFile.Rename(mNewName) ' Формирование отчета о переименовании if errResult = 0 then mResultText = mResultText & "File " & mCurrentFile.Name & " renamed to " _ & mNewName & vbCrLf else mResultText = mResultText & "Error at renaming " & mCurrentFile.Name & _ " file" & vbCrLf errResult = 0 end if Next ' Вывод отчета о переименовании Wscript.Echo(mResultText)
Аналогично приведенному примеру можно совершать и другие действия с файлами, так как класс CIM_DataFile поддерживает методы: копирование, удаление, переименование, NTFS-сжатие, смена разрешений, смена владельца.
Пример использования классов оборудования компьютера для получения информации о количестве портов USB 2.0 и используемых USB-устройствах:
iCounter = 0 ' Целевой компьютер mComputer = "." ' Подключение к пространству имен целевого компьютера Set mSWbemServices = GetObject("winmgmts:\\" & mComputer & "\Root\CIMv2") ' Получение колекции USB-контроллеров Set mControllerList = mSWbemServices.ExecQuery("Select * From Win32_USBController") ' Обработка USB-контроллеров For Each mCurrentController in mControllerList If Instr(mCurrentController.Name, "Enhanced") Then iCounter = iCounter + 1 End If Next ' Формирование отчета о USB-контроллерах mResultText = "USB 2.0 Ports count: " & iCounter & vbCrLf & vbCrLf ' Получение колекции USB-устройств Set mDeviceList = mSWbemServices.ExecQuery ("Select * From Win32_USBControllerDevice") ' Обработка USB-устройств For Each mCurrentDevice in mDeviceList mDeviceName = mCurrentDevice.Dependent mDeviceName = Replace(mDeviceName, Chr(34), "") mDeviceNames = Split(mDeviceName, "=") mDeviceName = mDeviceNames(1) ' Получение свойств каждого устройства по его идентификатору Set mUSBDeviceList = mSWbemServices.ExecQuery("Select * From Win32_PnPEntity " _ & "Where DeviceID = '" & mDeviceName & "'") ' Обработка свойств устройства For Each mCurrentUSBDevice in mUSBDeviceList ' Формирование отчета о USB-устройствах mResultText = mResultText & mCurrentUSBDevice.Description & vbCrLf Next Next ' Вывод результата Wscript.Echo(mResultText)
Пример использования класса свойств принтеров для получения информации о настройках принтеров:
' Целевой компьютер mComputer = "." ' Задание констант кодов типов доступа к текстовому файлу Const ForReading = 1 Const ForWriting = 2 Const ForAppending = 8 ' Создание объекта оболочки и получение текущей директории Set oShell = CreateObject("wscript.shell") sWorkDirectory = oShell.CurrentDirectory ' Создание объекта файловой системы и файла Set oFSO = CreateObject ("Scripting.FileSystemObject") Set mResultFile = oFSO.OpenTextFile(sWorkDirectory & "\PrinterList.txt", ForWriting, True, 0) ' Подключение к пространству имен целевого компьютера Set mSWbemServices = GetObject("winmgmts:\\" & mComputer & "\Root\CIMv2") ' Получение колекции локальных принтеров Set mPrinterList = mSWbemServices.ExecQuery("SELECT * FROM Win32_Printer WHERE Local = True") ' Запись заголовка в файл mResultFile.WriteLine("Name;Comment;Location;ShareName;DriverName;PortName;") ' Обработка каждого принтера For Each mCurrentPrinter in mPrinterList mResultFile.WriteLine(mCurrentPrinter.Name & ";" & mCurrentPrinter.Comment & ";" & _ mCurrentPrinter.Location & ";" & mCurrentPrinter.ShareName & ";" & _ mCurrentPrinter.DriverName & ";" & mCurrentPrinter.PortName & ";") Next ' Закрытие файла mResultFile.Close
Пример использования класса свойств сетевого адаптера для изменения конфигурации сетевой карты — перевода с DHCP на статическую конфигурацию:
' Целевой компьютер mComputer = "." ' Новые сетевые параметры задаются конкретными значениями ' Аналогичные параметры задаются значением "The same" ' Пустые парамеры задаются значением "" mNewIPAddress = "The same" mNewSubnetMask = "The same" mNewDNSServer = "The same" mNewDefaultIPGateway = "The same" mNewWINSPrimaryServer = "The same" mNewWINSSecondaryServer = "The same" ' Рабочие массивы Dim mDNSServerList() Dim mDefaultIPGatewayList() Dim mGatewayMetricList() Dim mNewDNSServerList() Dim mNewDefaultIPGatewayList() Dim mNewGatewayMetricList() ' Подключение к пространству имен целевого компьютера Set mSWbemServices = GetObject("winmgmts:\\" & mComputer & "\Root\CIMv2") ' Получение коллекции адаптеров с указанным IP-адресом Set mAdapterList = mSWbemServices.ExecQuery ("Select * From Win32_NetworkAdapter") ' Получение MAC-адреса адаптера локального адаптера For Each mCurrentAdapter In mAdapterList If InStr(LCase(mCurrentAdapter.NetConnectionID), "локальн") > 0 _ Or InStr(LCase(mCurrentAdapter.NetConnectionID), "local") > 0 Then mMACAddress = mCurrentAdapter.MACAddress mCaption = mCurrentAdapter.Caption Exit For End If Next ' Получение коллекции параметров адаптера с указанным MAC-адресом Set mAdapterConfigList = mSWbemServices.ExecQuery _ ("Select * From Win32_NetworkAdapterConfiguration WHERE MACAddress = '" _ & mMACAddress & "'") ' Получение текущих параметров сетевого адаптера с указанным MAC-адресом For Each mCurrentAdapterConfig In mAdapterConfigList ' IP-адрес If IsNull(mCurrentAdapterConfig.IPAddress) = False Then For Each mCurrentIPAddress In mCurrentAdapterConfig.IPAddress mIPAddress = mCurrentIPAddress Exit For Next End If If mNewIPAddress = "The same" Then mNewIPAddress = mIPAddress mNewIPAddressList = Array(mNewIPAddress) ' Маска подсети If IsNull(mCurrentAdapterConfig.IPSubnet) = False Then For Each mCurrentIPSubnet In mCurrentAdapterConfig.IPSubnet mSubnetMask = mCurrentIPSubnet Exit For Next End If If mNewSubnetMask = "The same" Then mNewSubnetMask = mSubnetMask mNewSubnetMaskList = Array(mNewSubnetMask) ' DNS сервера If IsNull(mCurrentAdapterConfig.DNSServerSearchOrder) = False Then iCounter = 0 For Each mCurrentDNSServer In mCurrentAdapterConfig.DNSServerSearchOrder Redim Preserve mDNSServerList(iCounter) mDNSServerList(iCounter) = mCurrentDNSServer iCounter = iCounter + 1 Next End If If mNewDNSServer = "The same" Then For iCounter = 0 To UBound(mDNSServerList) Redim Preserve mNewDNSServerList(iCounter) mNewDNSServerList(iCounter) = mDNSServerList(iCounter) Next Else For iCounter = 0 To UBound(Split(mNewDNSServer,";")) Redim Preserve mNewDNSServerList(iCounter) mNewDNSServerList(iCounter) = Split(mNewDNSServer,";")(iCounter) Next End If ' Шлюзы If IsNull(mCurrentAdapterConfig.DefaultIPGateway) = False Then iCounter = 0 For Each mCurrentDefaultIPGateway In mCurrentAdapterConfig.DefaultIPGateway Redim Preserve mDefaultIPGatewayList(iCounter) mDefaultIPGatewayList(iCounter) = mCurrentDefaultIPGateway Redim Preserve mGatewayMetricList(iCounter) mGatewayMetricList(iCounter) = iCounter + 1 iCounter = iCounter + 1 Next End If If mNewDefaultIPGateway = "The same" Then For iCounter = 0 To UBound(mDefaultIPGatewayList) Redim Preserve mNewDefaultIPGatewayList(iCounter) mNewDefaultIPGatewayList(iCounter) = mDefaultIPGatewayList(iCounter) Redim Preserve mNewGatewayMetricList(iCounter) mNewGatewayMetricList(iCounter) = iCounter + 1 Next Else For iCounter = 0 To UBound(Split(mNewDefaultIPGateway,";")) Redim Preserve mNewDefaultIPGatewayList(iCounter) mNewDefaultIPGatewayList(iCounter) = Split(mNewDefaultIPGateway,";")(iCounter) Redim Preserve mNewGatewayMetricList(iCounter) mNewGatewayMetricList(iCounter) = iCounter + 1 Next End If ' WINS сервера If IsNull(mCurrentAdapterConfig.WINSPrimaryServer) = False Then mWINSPrimaryServer = mCurrentAdapterConfig.WINSPrimaryServer End If If mNewWINSPrimaryServer = "The same" Then If IsNull(mCurrentAdapterConfig.WINSPrimaryServer) = True Then mNewWINSPrimaryServer = "" Else mNewWINSPrimaryServer = mWINSPrimaryServer End If End If If IsNull(mCurrentAdapterConfig.WINSSecondaryServer) = False Then mWinsSecondaryServer = mCurrentAdapterConfig.WINSSecondaryServer End If If mNewWinsSecondaryServer = "The same" Then If IsNull(mCurrentAdapterConfig.WINSSecondaryServer) = True Then mNewWinsSecondaryServer = "" Else mNewWinsSecondaryServer = mWINSSecondaryServer End If End If Exit For Next ' Формирование сообщения по текущей и по будущей конфигурациям сетевого адаптера mInfoMessage = "Network adapter: " & mCaption & vbCrLf _ & "MAC address: " & mMACAddress & vbCrLf _ & "Current configuration:" & vbCrLf _ & vbTab & "IP address: " & mIPAddress & vbCrLf _ & vbTab & "Subnet mask: " & mSubnetMask & vbCrLf _ & vbTab & "Default Gateway: " & Join(mDefaultIPGatewayList,";") & vbCrLf _ & vbTab & "DNS servers: " & Join(mDNSServerList,";") & vbCrLf _ & vbTab & "WINS Primary Server: " & mWINSPrimaryServer & vbCrLf _ & vbTab & "WINS Secondary Server: " & mWINSSecondaryServer & vbCrLf _ & "New configuration:" & vbCrLf _ & vbTab & "IP address: " & mNewIPAddress & vbCrLf _ & vbTab & "Subnet mask: " & mNewSubnetMask & vbCrLf _ & vbTab & "Default Gateway: " & Join(mNewDefaultIPGatewayList,";") & vbCrLf _ & vbTab & "DNS servers: " & Join(mNewDNSServerList,";") & vbCrLf _ & vbTab & "WINS Primary Server: " & mNewWINSPrimaryServer & vbCrLf _ & vbTab & "WINS Secondary Server: " & mNewWINSSecondaryServer & vbCrLf _ & vbCrLf & "Please confirm the changes" & mNewWINSSecondaryServer & vbCrLf ' Окно подтверждения изменения настроек сетевого параметра mChangeFlag = MsgBox(mInfoMessage, vbOKCancel, "Network card settings change") If mChangeFlag = vbOK Then ' Установка нового IP адреса For Each mCurrentAdapterConfig in mAdapterConfigList errEnable = mCurrentAdapterConfig.EnableStatic _ (mNewIPAddressList, mNewSubnetMaskList) errGateways = mCurrentAdapterConfig.SetGateways _ (mNewDefaultIPGatewayList, mNewGatewayMetricList) errWINS = mCurrentAdapterConfig.SetWINSServer _ (mNewWINSPrimaryServer, mNewWinsSecondaryServer) errDNS = mCurrentAdapterConfig.SetDNSServerSearchOrder _ (mNewDNSServerList) Exit For Next ' Pезультат операции mInfoMessage = "Operation result:" & vbCrLf _ & "IP address error code: " & errEnable & vbCrLf _ & "Gateway error code: " & errGateways & vbCrLf _ & "DNS error code: " & errDNS & vbCrLf _ & "WINS error code: " & errWINS & vbCrLf Else mInfoMessage = "The operation is canceled" End If Wscript.Echo(mInfoMessage)
Ресурсы WMI доступны не только через скрипты, к ним можно обращаться из других языков программирования и даже из программ.
Существует два способа обращения к WMI через Visual Basic.NET.
Первый способ берет свое начало из скриптов VBS. Он использует обращение к инстументу winmgmts, как это делалось в методе моникера:
oComputerSystem = GetObject("winmgmts:[Options!]WMINameSpace).ExecQuery(WQLQuery)
Пример запроса модели комьютера (консольное приложение)
Module TestModule Sub Main() ' Объявление переменных Dim oWMIObject As Object Dim oComputerSystem As Object Try ' Подключение к WMI oWMIObject = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") ' Выполнение запроса oComputerSystem = oWMIObject.ExecQuery("Select * from Win32_ComputerSystem") For Each oConfigutation As Object In oComputerSystem ' Вывод результатов в консоль Console.Write(oConfigutation.Model) Next Catch ex As Exception Console.Write("Ошибка запроса к WMI") End Try End Module
Второй способ является более правильным с точки зрения Visual Studio. Он использует классSystem.Managementдля запросов к WMI, в котором указываются пространство WMI, параметры подключения и WQL запрос:
' Задание параметров подключения mOptions = New Management.ConnectionOptions([Options]) ' Задания WMI пространства имен mScope = New Management.ManagementScope(WMINameSpace, mOptions) ' Задание WQL запроса mQuery = New Management.ObjectQuery(WQLQuery) ' Создание объекта поиска по WMI с указанными параметрами mSearcher = New Management.ManagementObjectSearcher(mScope, mQuery) ' Выполнение запроса mQueryCollection = mSearcher.Get()
Использование полученных объектов аналогично использованию в скриптах.
Пример запроса сервисов локального комьютера (консольное приложение):
Module TestModule Sub Main() ' Объявление переменных Dim mOptions As Management.ConnectionOptions Dim mScope As Management.ManagementScope Dim mQuery As Management.ObjectQuery Dim mSearcher As Management.ManagementObjectSearcher Dim mQueryCollection As Management.ManagementObjectCollection ' Задание параметров подключения mOptions = New Management.ConnectionOptions ' Задания WMI пространства имен mScope = New Management.ManagementScope("\\.\root\cimv2", mOptions) ' Задание WQL запроса mQuery = New Management.ObjectQuery("SELECT * FROM Win32_Service") ' Создание объекта поиска по WMI с указанными параметрами mSearcher = New Management.ManagementObjectSearcher(mScope, mQuery) Try ' Выполнение запроса mQueryCollection = mSearcher.Get() ' Вывод результатов в консоль For Each mObject As Management.ManagementObject In mQueryCollection Console.WriteLine(mObject.Item("DisplayName").ToString) Next Catch ex As Exception Console.Write("Ошибка запроса к WMI") End Try End Sub End Module
В качестве примера прораммы использования WMI в Visual Basic.Net представлено консольное приложение управления сервисом печати компьютера. Приложение запрашивает модель компьютера и выводит результат в консоль. После чего запрашивает состояние сервиса печати и, если он остановлен, предлагает запустить его.
Приложение разделено на две части: класс, который компилируется в динамическую библиотеку DLL, и программа, которая собирается в исполняемый файл EXE.
Листинг файла WMIClass.vb:
Public Class WMIClass ' Функция получения модели копьютера #Region "GetModel 1.0" Public Function GetModel(Optional ByVal IPAddress As String = ".") As String Dim mTempValue As String = Nothing Try Dim oComputerSystem = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ IPAddress & "\root\cimv2").ExecQuery("Select * from Win32_ComputerSystem") For Each oConfigutation As Object In oComputerSystem mTempValue = oConfigutation.Model Next Catch ex As Exception End Try Return mTempValue End Function #End Region ' Функция получения состояния сервиса компьютера #Region "GetServiceState 1.0" Public Function GetServiceState(Optional ByVal IPAddress As String = ".", _ Optional ByVal ServiceName As String = "winmgmt") As Boolean Dim mOptions As Management.ConnectionOptions Dim mScope As Management.ManagementScope Dim mQuery As Management.ObjectQuery Dim mSearcher As Management.ManagementObjectSearcher mOptions = New Management.ConnectionOptions mScope = New Management.ManagementScope("\\" & IPAddress & "\root\cimv2", mOptions) mQuery = New Management.ObjectQuery("SELECT * FROM Win32_Service " & _ "WHERE DisplayName = '" & ServiceName & "'") mSearcher = New Management.ManagementObjectSearcher(mScope, mQuery) Try Dim mQueryCollection As Management.ManagementObjectCollection = mSearcher.Get() For Each mObject As Management.ManagementObject In mQueryCollection If mObject("State") = "Running" Then Return True Else Return False End If Next Return False Catch ex As Exception Return False End Try End Function Public Function GetServiceStateFull(Optional ByVal IPAddress As String = ".", _ Optional ByVal ServiceName As String = "winmgmt") As String Dim mOptions As Management.ConnectionOptions Dim mScope As Management.ManagementScope Dim mQuery As Management.ObjectQuery Dim mSearcher As Management.ManagementObjectSearcher mOptions = New Management.ConnectionOptions mScope = New Management.ManagementScope("\\" & IPAddress & "\root\cimv2", mOptions) mQuery = New Management.ObjectQuery("SELECT * FROM Win32_Service " & "WHERE DisplayName = '" & ServiceName & "'") mSearcher = New Management.ManagementObjectSearcher(mScope, mQuery) Try Dim mQueryCollection As Management.ManagementObjectCollection = mSearcher.Get() For Each mObject As Management.ManagementObject In mQueryCollection Return mObject("State") Next Return "No data" Catch ex As Exception Return "No data" End Try End Function #End Region ' Процедура управления сервисом компьютера #Region "Manage Service 1.0" Public Sub ManageService(Optional ByVal IPAddress As String = ".", _ Optional ByVal ServiceName As String = "winmgmt", _ Optional ByVal Action As String = "StartService") Dim mOptions As Management.ConnectionOptions Dim mScope As Management.ManagementScope Dim mQuery As Management.ObjectQuery Dim mSearcher As Management.ManagementObjectSearcher Dim mQueryCollection As Management.ManagementObjectCollection mOptions = New Management.ConnectionOptions mScope = New Management.ManagementScope("\\" & IPAddress & "\root\cimv2", mOptions) mQuery = New Management.ObjectQuery("SELECT * FROM Win32_Service " & _ "WHERE DisplayName = '" & ServiceName & "'") mSearcher = New Management.ManagementObjectSearcher(mScope, mQuery) Try mQueryCollection = mSearcher.Get() For Each mObject As Management.ManagementObject In mQueryCollection mObject.InvokeMethod(Action, Nothing) Next Catch ex As Exception End Try End Sub #End Region End Class
Листинг файла TestModule.vb:
Module TestModule ' Создание экземпляра класса WMIClass Private mWMIClass_Instance As New WMIClass Sub Main() Dim mKeyNumber As Integer ' Получение модели компьютера и результата в консоль Console.WriteLine("Модель компьютера: " & mWMIClass_Instance.GetModel()) ' Проверка состояния сервиса "Диспетчер печати" If mWMIClass_Instance.GetServiceState(, "Диспетчер печати") = True Then Console.WriteLine("Служба ""Диспетчер печати"" запущена") Else Console.WriteLine("Служба ""Диспетчер печати"" остановлена") Console.Write("Запустить службу ""Диспетчер печати""? Y/N: ") ' Чтение символа с клавиатуры mKeyNumber = Console.Read If mKeyNumber = 89 Or mKeyNumber = 121 Then Console.WriteLine("Запуск службы ""Диспетчер печати""...") ' Попытка запуска сервиса "Диспетчер печати" mWMIClass_Instance.ManageService(, "Диспетчер печати", "StartService") ' Ожидание 5 секунда Threading.Thread.Sleep(5000) ' Проверка состояния сервиса "Диспетчер печати" If mWMIClass_Instance.GetServiceState(, "Диспетчер печати") = True Then Console.WriteLine("Служба ""Диспетчер печати"" успешно запущена") Else Console.WriteLine("Запуск службы ""Диспетчер печати"" не удался") End If End If End If Console.WriteLine("Нажмите любую клавишу для продолжения") ' Ожидание нажатия любой клавиши Console.ReadKey() End Sub End Module
Для того, чтобы облегчить написание скриптов и программ, существуют специальные утилиты, которые помогают просмотреть структуру пространства WMI и показавают примеры использования всех классов. Наиболее распространенные утилиты — это Scriptomatic и WMI Code Creator.
Инструмент Scriptomatic предствляет из себя HTA-приложение, которое генерирует код, использующий WMI, на VBSScript, JScript, Perl и Python. Сам по себе WMI может оказаться трудным для изучения, поэтому рекомендуется использовать Scriptomatic для освоения классов WMI, а также для быстрого создания шаблонов обращения к ресерсум WMI. Scriptomatic позволяет выбрать интересующий объект WMI, а затем генерирует код на указанном языке программирования. Полученный код можно выполнить непосредственно в оболочке программы, а результаты вывести в консоль, текстовый файл, HTML, Excel или XML. Инструмент доступен на сайте Microsoft по этой ссылке.
WMI Scriptomatic — Инициализация
WMI Scriptomatic — Win32_OpepatingSystem
Программа WMI Code Creator представляет из себя генератор кода, который использует WMI для получения информации и для осуществления задач упраления компьютерами. Программа может помочь научиться использовать WMI-скрипты и WMI-приложения для управления как локальным, так и удаленным компьютером. Инструмент доступен на сайте Microsoft по этой ссылке.
Используя WMI Code Creator можно найти любую информацию о компьютере: имя и версия операционной системы, свободное место на диске, состояние сервисов и так далее. Можно выполнить метод из WMI класса для осуществления управления компьютером: создать или удалить сервис, запустить или закрыть программы, назначить разрешения на папку или файл и многое другое. Этот инструмент так же позволяет просматривать доступное WMI-пространство и WMI-классы, чтобы найти нужную для программирования инстанцию с ее описанием, свойствами, методами и примером использования.
WMI Code Creator — Query
WMI Code Creator — Method
WMI Code Creator — Event
WMI Code Creator — Namespace
Итак, Windows Management Instrumentation — это мощный инструмент для администрирования операционных систем семейства Windows с помощью скриптов. С помощью WMI можно управлять устройствами, учетными записями, сервисами, процессами, сетевыми интерфейсами и другими программами, которые расширяют базовую структуру WMI своими классами.
Помимо скриптов WMI может применяться и в полноценных программах, то есть программисты могут внедрять запросы к WMI в исполняемый код, завязывая свою программу с работой WMI, благодаря чему программа становится проще и легче, но зависимой от правильности работы Windows Management Instrumentation.
Интересно, что новая командная оболочка Windows PowerShell связана с WMI как технической точки зрения, так и с точки зрения создания запросов — утилита Wmic.exe функционирует в некотором смысле аналогичным образом. В Windows PowerShell поддержка WMI, представлена в точно таком же согласованном объектном виде, как и другие возможности данной оболочки, поэтому при изучении этой оболочки применение WMI не становится такой сложной задачей, как это было в VBScript — не нужно изучать синтаксис и механизмы языка, отличного от языка скрипта.
Инструменты для написания скриптов ScriptReference.zip.
Более подробно о Windows PowerShell можно будет прочитать в следующих выпусках статей сайта www.SysEngineering.ru.
Виталий Бочкарев
Хороший материал, взятый из журнала samag.ru [14], автор Константин Леонтьев. Тем, кто его до сих пор не читает, читать немедленно…
[Вы всё ещё не используете WMI?]
Если ты один из большинства админов, ты частенько грустишь, выглядывая из окна и наблюдая, как некоторые твои собратья ездят на своих «Ягуарах» и «Порше», или готовятся дернуть в Монте-Карло или какое-нибудь другое экзотическое место. И, конечно же, ты говоришь себе: «Я знаю о системном администрировании столько же, сколько и они, но почему именно у них есть клёвые тачки, яхты и часы «Ролекс»?..». Что ж, мы здесь для того, чтобы приоткрыть тебе небольшой секрет. Это все потому, что они знают, как писать WMI-скрипты, а ты – нет! Microsoft TechNet: Bob Wells, Dean Tsaltas, Ethan Wilansky и Greg Stemp |
Начиная карьеру системного администратора, Вы вероятно и не задумывались о том, что вместе с Вашим профессиональным ростом будет расти размер и сложность обслуживаемых систем. И вот наступил момент, когда вы поняли, что нужно принципиально новое решение, для того чтобы справляться с огромным количеством рутины, да ещё и в разных офисах вашей компании. Вероятнее всего, Вы уже немного знакомы с WMI на практике и используете некоторые готовые сценарии WMI для решения повседневных задач. Но согласитесь, что эффективное использование технологии начинается только тогда, когда вы понимаете ее архитектуру и четко представляете весь спектр возможностей, которые эта технология может вам предоставить.
Основная моя цель – кратко изложить основы, необходимые для эффективного использования вами этой технологии и представить вам набор рецептов по ее применению в реальных условиях.
Вы получите практический навык работы со всеми основными средствами WMI, выполнив несколько простых, но весьма полезных упражнений. Я предполагаю, что вы немного знакомы с программированием на VBScript и с азами языка SQL, а также имеете общее представление об объектно-ориентированном программировании. Обратите внимание на готовые примеры кода, которые помогут вам в Вашей работе.
Что такое WMI?
Формально: аббревиатура WMI – это Windows Management Instrumentation (инструментарий управления Windows). Из названия понятно, для чего создана и применяется эта технология. Стоит лишь добавить, что она давно перешагнула рамки управления только операционной системой Windows и позволяет контролировать множество других совместимых с ней приложений.
По своей сути WMI – это расширенная и адаптированная компанией Microsoft реализация стандарта WBEM (WebBased Enterprise Management компании DMTF Inc [1]). В основе WBEM лежит идея создания универсального интерфейса мониторинга и управления к различным системам и компонентам распределенной информационной среды предприятия с использованием объектно-ориентированной идеологии и широко распространенных веб-технологий представления информации: протоколов XML и HTTP. Стандарт WBEM является правопреемником стандарта DMI (Desktop Management Interface).
В основе структуры представления данных в стандарте WBEM лежит CIM (Common Information Model – модель информации общего типа), реализующая объектно-ориентированный подход к представлению компонентов систем как классов со своим набором свойств и методов, а также принципов наследования.
Основное средство для описания новых элементов модели CIM – это синтаксис языка Managed Object Format (MOF), который является текстовым и легко понятным человеку. Таким образом, любое приложение или драйвер в операционной системе, которая поддерживает стандарт WBEM, может добавить к системной модели CIM свой набор классов. Такое расширение модели CIM позволяет легко интегрировать в единую систему мониторинга и управления все новые и новые приложения. Для этой интеграции приложение должно лишь зарегистрировать свои классы в существующей модели CIM и обеспечить стандартные вызовы встроенных процедур для создания объектов этих классов и наполнения их свойствами и методами. Набор этих процедур оформляется, как WMI Provider – специальная библиотека, являющаяся мостом между любым приложением и ядром службы WMI.
Таким образом, WMI – это открытая унифицированная библиотека (репозиторий) однотипных интерфейсов доступа к параметрам, настройки и свойствам различных систем и их компонентов. Архитектура WMI представлена на рис. 1.
Рисунок 1. Архитектура WMI
Многие производители программного и аппаратного обеспечения ведут разработку ПО в соответствии со стандартом WBEM. Как следствие, это ПО совместимо и с WMI, а значит, может управляться через единый и удобный интерфейс.
Классы, объекты, свойства и методы
Поскольку WMI построена по объектно-ориентированному принципу, то все данные об операционной системе, ее свойствах, управляемых приложениях и обнаруженном оборудовании представлены в виде объектов. Каждый тип объекта описан классом, в состав которого входят свойства и методы. Определения классов описаны в MOF-файлах, а объекты этих классов с заполненными свойствами и доступными методами при их вызове возвращаются WMI-провайдерами. Управляет созданием и удалением объектов, а также вызовом их методов служба CIM Object Manager.
Получается, что если мы хотим управлять настройками сетевого адаптера, то мы должны запросить у CIM Object Manager экземпляр объекта нужного нам сетевого адаптера (забегая вперед, скажу, что этот объект принадлежит классу Win32_NetworkAdapterConfiguration) и вызвать нужные нам методы. В частности, для того чтобы обновить аренду адреса на DHCP сервере, достаточно вызвать метод RenewDHCPLease экземпляра объекта Win32_NetworkAdapterConfiguration.
Обзор средств работы с WMI для администратора
Начнем фактическое знакомство с WMI с обзора утилит, которые позволяют вам работать с WMI на ОС семейства Windows. Условно разделим этот набор утилит на поставляемые с операционной системой по умолчанию и набор утилит, которые потребуется скачивать с сайта компании Microsoft. К первой категории относятся следующие утилиты:
• wmimgmt.msc – оснастка консоли MMC, позволяющая в целом управлять самой системой WMI на выбранном компьютере.
• Winmgmt.exe – консольная утилита управления WMI. Выполняет аналогичные действия, что и консоль MMC wmimgmt.msc. Кроме того, является исполняемым файлом сервиса WMI в системе. Для запуска из консоли используется с опцией /exe (winmgmt.exe /exe).
• Wbemtest.exe – графическая утилита для интерактивной работы с WMI. Удобна для тестирования классов и методов, просмотра свойств и т. п.
• Wmic.exe – консольная утилита для вызова объектов и методов WMI (WMI Console) – присутствует только в Windows XP и Windows Server 2003.
• mofcomp.exe – компилятор MOF-файлов. Служит для расширения репозитория WMI и тонких операций с библиотекой классов WMI, а также для «ремонта» нарушенного репозитория.
Ко второй категории средств для работы с WMI, которые требуется дополнительно устанавливать, относится:
• WMI Code Creator 1.0 – очень удобная и полезная утилита для создания готовых сценариев WMI. Поддерживает языки Visual Basic Script, C# и Visual Basic .NET [2].
• WMI Administrative Tools – комплект средств в составе: WMI CIM Studio, WMI Event Registration, WMI Event Viewer и WMI Object Browser). Удобная среда разработки и тестирования WMI-классов и методов [3].
• Scriptomatic 2.0 – мастер в формате Hyper Text Application (HTA). Удобна для создания готовых сценариев и на различных скриптовых языках. Поддерживает Visual Basic Script, Perl, Java Script и Python [4].
• Tweakomatic Utility – утилита в формате Hyper Text Application (HTA). Содержит множество настроек системы, обычно доступных через утилиты-твикеры (например, Windows XP Power Toys TweakUI), для которых позволяет сгенерировать WMI-скрипты для их автоматической настройки. Весьма полезна при разработке сценариев автоматизированной установки и настройки [5].
Все утилиты, относящиеся ко второй категории, можно бесплатно скачать с сайта компании Microsoft по ссылкам, перечисленным в конце статьи. Полезно будет так же посетить раздел загрузки средств работы со скриптами [6] и общий раздел загрузки средств работы с WMI [7].
Для того, чтобы рассмотреть возможности и особенности всех средств работы с WMI, которые перечислены выше, не хватит и целого журнала, поэтому мы кратко остановимся на некоторых из них, на мой взгляд, наиболее полезных и (или) наиболее употребимых. Собственно, к таким я отношу следующие утилиты: WBEMTEST, WMIC, WMI Administrative Tools и довольно новую, но весьма полезную и удачную утилиту WMI Code Creator 1.0.
Надо отметить, что существуют и другие утилиты и средства работы с WMI, в том числе разработанные не компанией Microsoft, однако формат статьи не позволяет нам на них останавливаться сколько-нибудь подробно. Об одном из этих средств я считаю своим долгом хотя бы упомянуть в этой статье – это ADSI Scriptomatic [8], позволяющее создавать скрипты для управления службой каталогов Microsoft Active Directory.
Все примеры в этой статье протестированы на операционной системе Windows XP Service Pack 2, однако должны также корректно работать и на более ранних версиях OS Windows вплоть до Windows 2000. Если вам потребуется использовать WMI на более ранних версиях ОС Windows, то вам необходимо будет установить WMI Core Components 1.5 [9] и последнюю версию Windows Scripting Host [10, 11] на эти ОС.
Знакомимся с утилитой WBEMTEST
Чтобы прямо сейчас посмотреть, какой набор классов определен в репозитории WMI на вашем персональном компьютере, достаточно запустить утилиту wbemtest.exe и установить флажок «Enable All Privileges», как показано на рис. 2.
Рисунок 2. Основное окно утилиты WBEMTEST
Далее нужно нажать кнопку «Connect…», в поле пространства имен вписать root\CIMv2, как это показано на рис. 3, и нажать кнопку «Connect».
Рисунок 3. Окно настройки подключения к репозиторию WMI утилиты WBEMTEST
Рисунок 4. Основное окно утилиты WBEMTEST после подключения к репозиторию WMI
Затем нажмите кнопку «Enum Classes…», выберите «Recursive», не заполняйте поле суперкласса и нажмите «Ok». В результате вы получите список классов, определенный в вашем репозитории WMI, в пространстве имен CIMv2. Найдите среди всех класс с названием Win32_OperatingSystem (CIM_OperatingSystem), как это показано на рис. 5.
Рисунок 5. Окно результатов запроса со списком всех классов WMI пространства имен CIMv2
Дважды щелкните курсором мыши по классу Win32_OperatingSystem, посмотрите его свойства. Пример того, как это выглядит, показан на рис. 6.
Рисунок 6. Окно свойств класса Win32_OperatingSystem
Далее нужно нажать кнопку «Instances» и в открывшемся окне дважды щелкнуть курсором мыши по строке в списке экземпляров операционных систем. В открывшемся окне свойств экземпляра операционной системы найдите свойство («Property») с названием «Name», как это показано на рис. 7.
Рисунок 7. Окно свойств экземпляра объекта класса Win32_OperatingSystem
Дважды кликните по свойству курсором мыши. В открывшемся окне редактора свойств, которое показано на рис. 8, скопируйте отображаемое значение в буфер обмена. Оно пригодится нам в дальнейшем.
Рисунок 8. Окно со значением свойства Name экземпляра объекта класса Win32_OperatingSystem
Далее закройте все окна, кроме основного окна программы wbemtest. В блокноте отредактируйте строку из буфера обмена следующем образом:
— Заключите строку в кавычки.
— До первых кавычек добавьте следующий текст: «Win32_Operating-System.Name=».
— Замените все одинарные обратные слеши на двойные.
В итоге у вас должна получиться примерно следующая строка (в зависимости от версии ОС и логического диска, куда она установлена):
Win32_OperatingSystem.Name=»Microsoft Windows XP Professional|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1″
Теперь давайте выполним следующее упражнение с утилитой wbemtest. В уже открытом окне утилиты wbemtest нажмем кнопку «Execute Method…» и в окошко «GetObjectPath» вставим строку, которую мы подготовили в блокноте. В появившемся окне (см. рис. 9) вызова метода экземпляра объекта выберите метод Reboot и нажмите кнопку «Execute!».
Рисунок 9. Окно вызова метода для экземпляра объекта класса Win32_OperatingSystem утилиты WBEMTEST
Поздравляю, Вы только что отправили свою операционную систему в перезагрузку, используя WMI. Если вы вдруг получили вместо перезагрузки сообщение об ошибке 0x80041062 «Privilege not held», то это означает, что вы забыли установить опцию «Enable All Privileges» до подключения к репозиторию WMI.
Теперь следует сказать (пока Windows перезагружается), что при подключении к пространству имен WMI вы можете подключаться не только на локальной машине, но и как следует из обзора WMI к любой удаленной. Главное, обладать на той машине необходимыми правами. Но об этих правах позднее! Для подключения к удаленной машине в окне подключения достаточно в поле Name Space указать строку вида \\\root\CIMv2 и указать учетные данные пользователя, обладающего необходимыми правами (например, Administrator). Пример этого показан на рис. 10.
Рисунок 10. Окно подключение к пространству имен WMI с явным указанием имени сервера
Не пробуйте подключаться к локальной машине, на которой запрашиваются объекты и методы WMI (например, на той, на которой сейчас выполняется утилита wbemtest), используя отличные от текущих учетные данные – все равно это у вас не получится. Это специальная защита для повышения локальной безопасности WMI, но о ней мы поговорим позже.
Утилита WMIC
Чтобы воспользоваться этой очень важной и полезной для администратора утилитой, достаточно запустить интерпретатор командной строки cmd.exe и в строке приглашения набрать WMIC. После этого у вас появится приглашение консоли WMI, как это показано на рис. 11.
Рисунок 11. Командное окно с запущенной утилитой WMIC в интерактивном режиме
Для получения справки по всем командам, доступным из консоли WMIC, достаточно в строке приглашения ввести команду «/?». Синтаксис каждой команды или глобальной опции вы можете посмотреть, введя ее название и знак вопроса. Например:
Так мы работаем с утилитой WMIC в интерактивном режиме. Однако ничто не мешает нам использовать ее и в пакетном режиме из наших BAT/CMD-сценариев. Например, в приглашении командной строки CMD можно написать:
и получить тот же результат.
Утилита WMIC создана для удобства использования WMI прямо из командной строки, поэтому наиболее употребимые классы WMI доступны для использования под псевдонимами (ALIAS). Вы можете самостоятельно определить псевдонимы для тех классов, для которых это еще не сделано, или добавить новые псевдонимы для тех классов WMI, которые уже их имеют.
Список псевдонимов, которые определены на Windows XP Service Pack 2 по умолчанию с их кратким описанием, приведены в таблице 1.
Таблица 1. Список псевдонимов утилиты WMIC и соответствие их классам WMI
Псевдоним | Описание | Имя класса WMI |
BASEBOARD | Управление материнской платой, она также называется motherboard, или системная плата. | Win32_BIOS |
BIOS | Управления базовыми сервисами ввода/вывода (Basic input/output services, BIOS). | Win32_BaseBoard |
BOOTCONFIG | Управление конфигурацией загрузки (Boot configuration management). | Win32_BootConfiguration |
CDROM | Управление приводом CD-ROM. | Win32_CDROMDrive |
COMPUTERSYSTEM | Управление системой компьютера. | Win32_ComputerSystem |
CPU | Управление процессовром. | WIN32_PROCESSOR |
CSPRODUCT | Получение от SMBIOS информации о компьютере как системном продукте. | Win32_ComputerSystemProduct |
DATAFILE | Управление данными файлов (DataFile Management). | CIM_DataFile |
DCOMAPP | Управление приложениями (DCOM Application management). | WIN32_DCOMApplication |
DESKTOP | Управление рабочим столом пользователя (User’s Desktop management). | WIN32_DESKTOP |
DESKTOPMONITOR | Desktop Monitor management | WIN32_DESKTOPMONITOR |
DEVICEMEMORYADDRESS | Управление адресами памяти устройств (Device memory addresses management). | Win32_DeviceMemoryAddress |
DISKDRIVE | Управление диском на физическом уровне (Physical disk drive management). | Win32_DiskDrive |
DISKQUOTA | Управление квотами NTFS пространства диска (Disk space usage for NTFS volumes). | Win32_DiskQuota |
DMACHANNEL | Управление каналами прямого доступа к памяти (Direct memory access, DMA channel management). | Win32_DMAChannel |
ENVIRONMENT | Управление настройками системного окружения (System environment settings management) | Win32_Environment |
FSDIR | Управление директориями файловой системы (Filesystem directory entry management). | Win32_Directory |
GROUP | Управление группами учетных записей (Group account management). | Win32_Group |
IDECONTROLLER | Управление контролером диска IDE (IDE Controller management). | Win32_IDEController |
IRQ | Управление сигналами прерываний (Interrupt request line, IRQ management). | Win32_IRQResource |
JOB | Предоставляет доступ к назначенным заданиям (jobs scheduled) с использованием службы назначенных заданий (schedule service). | Win32_ScheduledJob |
LOADORDER | Управление службами системы, которые задают зависимости запуска (execution dependencies). | Win32_LoadOrderGroup |
LOGICALDISK | Управление дисковыми локальными устройствами хранения (Local storage device management). | Win32_LogicalDisk |
LOGON | Управление сессиями пользователей (LOGON Sessions). | Win32_LogonSession |
MEMCACHE | Управление кэшем (Cache memory management). | WIN32_CACHEMEMORY |
MEMLOGICAL | Управление памятью системы (как сконфигурирована карта памяти, и как память доступна для приложений и сервисов). | Win32_LogicalMemoryConfiguration |
MEMPHYSICAL | Управление памятью компьютера на физическом уровне (Computer system’s physical memory management). | Win32_PhysicalMemoryArray |
NETCLIENT | Управление клиентом сети (Network Client management). | WIN32_NetworkClient |
NETLOGIN | Управление информацией учетной записи сети для отдельного пользователя. | Win32_NetworkLoginProfile |
NETPROTOCOL | Управление протоколами и их сетевыми характеристиками. | Win32_NetworkProtocol |
NETUSE | Управление активным сетевым соединением. | Win32_NetworkConnection |
NIC | Управление сетевым адаптером (Network Interface Controller, NIC). | Win32_NetworkAdapter |
NICCONFIG | Управление конфигурацией сетевого адаптера. | Win32_NetworkAdapterConfiguration |
NTDOMAIN | Управление доменом NT. | Win32_NTDomain |
NTEVENT | Получение доступа к логам событий (Entries in the NT Event Log). | Win32_NTLogEvent |
NTEVENTLOG | Управление файлом лога (NT eventlog file management). | Win32_NTEventlogFile |
ONBOARDDEVICE | Управление общими адаптерами, установленными в материнскую плату (system board). | Win32_OnBoardDevice |
OS | Управление инсталлированными операционными системами. | Win32_OperatingSystem |
PAGEFILE | Управление виртуальной памятью и её свопом на диск. | Win32_PageFileUsage |
PAGEFILESET | Установка параметров файла свопа. | Win32_PageFileSetting |
PARTITION | Управление логическими разделами физического диска (Management of partitioned areas of a physical disk). | Win32_DiskPartition |
PORT | Управление портами ввода/вывода (I/O port management). | Win32_PortResource |
PORTCONNECTOR | Управление физическим соединением портов (Physical connection ports management). | Win32_PortConnector |
PRINTER | Printer device management | Win32_Printer |
PRINTERCONFIG | Управление конфигурацией принтера. | Win32_PrinterConfiguration |
PRINTJOB | Управление заданиями принтера. | Win32_PrintJob |
PROCESS | Управление процессами. | Win32_Process |
PRODUCT | Управление задачей инсталляционных пакетов (Installation package task management). | Win32_Product |
QFE | Быстрое исправление ошибок (Quick Fix Engineering). | Win32_QuickFixEngineering |
QUOTASETTING | Установка информации о квотах, установленных для тома диска (Setting information for disk quotas on a volume). | Win32_QuotaSetting |
RECOVEROS | Информация, которая была захвачена из памяти при крахе системы. | Win32_OSRecoveryConfiguration |
REGISTRY | Управление реестром системы. | Win32_Registry |
SCSICONTROLLER | Управление контроллером SCSI. | Win32_SCSIController |
SERVER | Управление информацией о сервере. | Win32_PerfRawData_PerfNet_Server |
SERVICE | Управление прикладными сервисами. | Win32_Service |
SHARE | Управление общими сетевыми ресурсами (Shared resource management). | Win32_Share |
SOFTWAREELEMENT | Управление элементами программных продуктов, установленных в системе. | Win32_SoftwareElement |
SOFTWAREFEATURE | Управление подмножествами программных продуктов SoftwareElement. | Win32_SoftwareFeature |
SOUNDDEV | Управление устройством звука. | WIN32_SoundDevice |
STARTUP | Управление командами автозапуска при входе пользователя в систему. | Win32_StartupCommand |
SYSACCOUNT | Управление учетной записью системы (System account management). | Win32_SystemAccount |
SYSDRIVER | Управление системным драйвером для базовой службы (Management of the system driver for a base service). | Win32_SystemDriver |
SYSTEMENCLOSURE | Управление физическим доступом к корпусу компьютера (Physical system enclosure management). | Win32_SystemEnclosure |
SYSTEMSLOT | Управление физичесими соединениями, включая порты, слоты и периферийные устройства, и точками проприетарных соединений. | Win32_SystemSlot |
TAPEDRIVE | Управление накопителем на магнитной ленте. | Win32_TapeDrive |
TEMPERATURE | Управление данными от датчика температуры (электронный термометр). | Win32_TemperatureProbe |
TIMEZONE | Управление данными часового пояса (Time zone data management). | Win32_TimeZone |
UPS | Управление источником бесперебойного питания (Uninterruptible power supply, UPS). | Win32_UninterruptiblePowerSupply |
USERACCOUNT | Управление учетными записями пользователей (User account management). | Win32_UserAccount |
VOLTAGE | Управление данными сенсора напряжения (электронный вольтметр). | Win32_VoltageProbe |
VOLUMEQUOTASETTING | Связывает установки дисковой квоты с определенным дисковым томом. | Win32_VolumeQuotaSetting |
WMISET | Управляет рабочими параметрами службы WMI. | Win32_WMISetting |
Теперь давайте попробуем использовать утилиту WMIC для работы с WMI из командной строки. Для начала выйдите из интерактивного режима консоли WMIC командой exit. Вы оказались в среде командного интерпретатора CMD. В приглашении наберите команду:
Вы получите список процессов, запущенных на вашем локальном компьютере. Теперь выполните команду:
wmic process list brief | find "cmd.exe"
Теперь список процессов ограничен только теми процессами, в имени исполняемого модуля которых присутствует строка «cmd.exe». Обратите внимание на PID процесса(ов).
Давайте попробуем отобрать интересующие нас процессы, используя непосредственно WMI и не прибегая к стандартным средствам командной строки. Для этого просто напишите:
wmic process where description='cmd.exe' list brief
Сравните полученные результаты. Запомните PID процесса CMD.EXE.
Вызовем метод Terminate для экземпляра объекта WMI. Так мы завершим интересующий нас процесс в системе. Для того чтобы однозначно определить процесс, который мы хотим завершить, нам нужно использовать его PID или какой-либо другой набор атрибутов процесса, которые позволяют его однозначно отличить от множества других процессов в системе. Для завершения процесса нам нужно вызвать метод WMI. Для этого существует команда CALL. Для того чтобы вывести справку по всем методам, применимым к объектам типа PROCESS (Win32_Process), наберите команду:
Среди них обратите внимание на метод Terminate – он принимает в качестве единственного входного параметра значение типа UINT32 (беззнаковое 32-разрядное целое) в качестве индекса причины завершения процесса. В данном случае этот параметр аналогичен Exit-коду.
Запустите четыре разных экземпляра процесса cmd.exe (откройте 4 командных окна). Еще раз выполните команду:
wmic process where description='cmd.exe' list brief
В результате вы получите в ответ примерно следующее:
HandleCount Name Priority ProcessId ThreadCount WorkingSetSize
28 cmd.exe 8 4648 1 2494464
28 cmd.exe 8 5156 1 2498560
28 cmd.exe 8 4940 1 2498560
31 cmd.exe 8 612 1 2703360
Итак, чтобы завершить конкретный процесс, просто наберите:
wmic process where processid='****' call terminate(0)
вместо звездочек укажите PID нужного вам экземпляра процесса cmd.exe.
Теперь давайте одной командой завершим все оставшиеся процессы cmd.exe, для этого просто введите команду:
wmic process where description='cmd.exe' call terminate(0)
Что за конструкция where и как еще ее можно использовать, мы разберем чуть позже в разделе «Язык запросов WQL».
Для того чтобы подключиться к репозиторию WMI на другом компьютере и выполнять все те же действия, при условии, что наша учетная запись обладает достаточными правами, нам всего лишь нужно немного модифицировать нашу командную строку. Теперь наши команды должны выглядеть примерно так:
wmic /NODE:server01 /USER:DOMAIN\Administrator /PASSWORD:qwerty /PRIVILEGES:ENABLE process where description='cmd.exe' list brief
Если же вы хотите выполнить какие-то действия, используя WMI не с одним, а с целой группой компьютеров, то достаточно написать команду с использованием WMIC и ключом «/node:@serverslist.txt»:
wmic /NODE:@serverslist.txt /USER:DOMAIN\Administrator /PASSWORD:qwerty /PRIVILEGES:ENABLE process where description='cmd.exe' list brief
В файле serverlist.txt в столбец или в строку должны быть перечислены имена (IP-адреса) хостов, на которых необходимо выполнить это действие.
В довершение краткого описания утилиты WMIC, следует сказать об еще одной, поистине замечательной, ее особенности – форматировании вывода. Практически все команды WMIC, которые возвращают информацию, могут ее форматировать разными способами. Для этого используется ключ «/format:». Форматирование производится с использованием технологии XSLT (шаблонов для преобразования XML). По умолчанию уже определен ряд готовых преобразований: CSV, HFORM, HMOF, HTABLE, HXML, RAWXML, TABLE, VALUE. Вы так же сами можете определить дополнительные шаблоны форматирования в формате XSLT и использовать их совместно с WMIC.
Краткое практическое знакомство c WMI CIM Studio
Это набор приложений Microsoft Internet Explorer, который позволяет с одной стороны очень тонко, с другой стороны довольно удобно работать с WMI. При этом вы можете как просматривать классы и вызывать методы, так и создавать события и даже модифицировать репозиторий WMI. Поэтому будьте очень осторожны. Если вы запускаете WMI CIM Studio на Windows XP Service Pack 2, то Internet Explorer предупредит вас о потенциальной угрозе безопасности. Вам следует разрешить заблокированное содержимое ActiveX.
На рис. 12 показан вид окна WMI CIM Studio. Слева вы видите набор классов WMI и их иерархии в том пространстве имен WMI, которое вы выбрали при подключении. Справа перечислены все свойства выбранного класса. Все методы класса перечислены на закладке Methods, а на закладке Associations показана «родословная» этого класса и других классов, которые выведены из него.
Рисунок 12. Окно утилиты WMI CIM Studio с открытыми свойствами класса Win32_OperatingSystem
Если вы хотите посмотреть все экземпляры объектов выбранного класса, существующие в вашей системе, то достаточно нажать кнопку со значком списка (четвертая справа кнопка в правой панели кнопок).
WMI CIM Studio очень удобный инструмент для поиска классов и свойств в огромном море репозитория WMI. Для поиска нажмите кнопку со значком бинокля и введите шаблон для поиска, например «network». Выберите область поиска (Class names, Class description, Property names) и нажмите «Go!». В целом WMI CIM Studio очень хороший инструмент для поиска и исследования репозитория WMI и для интерактивного анализа состояния экземпляров объектов WMI.
Язык запросов WQL
Теперь нам следует разобраться, что же такое WQL, а также каким образом в разделе, где описана работа WMIC, мы делали выборку объектов WMI по определенным критериям. Разбирая эту тему, полезно вспомнить, что объектно-ориентированная модель представления данных хорошо ложится на структуру реляционных баз данных. В частности можно провести следующие аналогии: определение таблицы данных (поля и их типы) – это классы объектов, строки в конкретной таблице – это экземпляры объектов данного класса. Каждое поле (столбец) в таблице – это свойство всех объектов данного класса. Каждая ячейка в конкретной строке – это свойство (property) конкретного экземпляра объекта. Связи таблиц и представления можно рассматривать как частный случай наследования. Триггеры и встроенные процедуры исходя из этой аналогии – это методы классов.
Собственно, для того чтобы удобно было работать с множественными экземплярами объектов WMI, используется язык WMI Query Language (WQL), который является подмножеством ANSI SQL.
Основное отличие WQL от ANSI SQL состоит в том, что WQL не позволяет производить изменения в данных WMI, т. е. фактически в WQL поддерживается лишь один оператор SQL: select. Кроме того, в операторе select языка WQL не поддерживаются следующие ключевые слова: DISTINCT, COUNT, JOIN, SUBSTRING, ORDER BY, UPPER, LOWER и DATEPART (эти ключевые слова поддерживаются в варианте Extended WQL (eWQL), реализованном в Microsoft SMS 2.0 и SMS 2003). Не поддерживаются арифметические операторы. Кроме того конструкции IS и IS NOT могут применяться только в сочетании с константой NULL. Языком WQL поддерживается оператор LIKE. Более подробно про шаблоны, применяемые совместно с оператором LIKE в WQL, можно ознакомиться в оригинальном описании WMI на сайте Microsoft [12, 13].
Ниже приведен пример некоторых типичных WQL-запросов:
SELECT * FROM Win32_LogicalDisk WHERE FileSystem IS NULL SELECT * FROM Win32_LogicalDisk WHERE FileSystem IS NOT NULL SELECT * FROM Win32_LogicalDisk WHERE FileSystem = "NTFS" SELECT * FROM Win32_DiskDrive WHERE Partitions < 2 OR SectorsPerTrack > 100 SELECT * FROM Win32_LogicalDisk WHERE (Name = "C:" OR Name = "D:") AND FreeSpace > 2000000 AND FileSystem = "NTFS" SELECT * FROM Win32_NTLogEvent WHERE Logfile = 'Application' SELECT * FROM Meta_Class WHERE __Class LIKE %Win32% SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA "Win32_NTLogEvent" GROUP WITHIN 600 BY TargetInstance.SourceName HAVING NumberOfEvents > 25
Вы можете поупражняться в запросах WMI с помощью уже хорошо известной вам утилиты WBEMTEST, нажав кнопку «Query» в ее главном окне.
Теперь вспомните утилиту командной строки WMIC, функции которой мы разбирали немного выше. В ее синтаксисе также могут использоваться WQL-запросы для удобства работы с наборами объектов одного класса. Чтобы использовать уже имеющиеся и проверенные WQL-запросы (большинство из них удобнее всего проверять утилитой WBEMTEST), из командной строки достаточно отбросить у WQL-запроса первую часть: «select * from». Затем заменить имя класса на его алиас (псевдоним) из таблицы 1 и при необходимости добавить после запроса вызов метода, формат вывода списка или запрос свойства объекта. Примеры того, что при этом получается, я уже приводил выше.
Если же среди псевдонимов в таблице 1 нет нужного вам класса, то есть два пути решения. Первый – добавить новый псевдоним для нового класса. Этот путь хорош, если с этим классом из WMIC вы будете работать только на этом компьютере. Если же вы хотите использовать команду wmic на разных компьютерах, в том числе и на тех, на которых такой алиас вы не определяли, то можно воспользоваться вторым способом. Второй способ позволяет явно использовать настоящее имя класса WMI при обращении к нему с помощью WMIC. Для этого используйте следующий синтаксис:
wmic path Win32_LogicalDisk WHERE FileSystem='NTFS' get /value
Заключение
Во второй части статьи [15] обсудим написание сценариев с использованием WMI и WSH. Будут разобраны особенности использования WMI в скриптах, из тех, которые обычно вызывают наибольшие затруднения у людей, начинающих работать с этой технологией. К таким темам я отношу: построение moniker string, использование различных пространств имен WMI, связка WMI и COM, использование различных языков программирования вместе с WMI, имперсонация, аутентификация и привилегии. Наконец, наиболее интересные моменты, связанные с подключением к удаленным компьютерам и обработкой системных событий с помощью WMI. В заключении мы обсудим готовые продукты, использующие WMI и стратегию развития этой технологии, а так же ее применения в информационных системах предприятий.
[Ссылки и литература]
1. Distributed Management Task Force Inc. site:dmtf.org.
2. WMICodeCreator.zip site:microsoft.com — WMI Code Creator 1.0.
3. WMITools.exe site:microsoft.com — WMI Administrative Tools.
4. Scriptomatic site:microsoft.com.
5. Tweakomatic Utility site:microsoft.com.
6. Microsoft Scripting Downloads Catalog site:msdn.microsoft.com.
7. WMI Downloads catalog site:msdn.microsoft.com.
8. ADSI Scriptomatic site:microsoft.com.
9. WMI Core 1.5 for Windows 9x, NT 4.0 SP4 site:microsoft.com.
10. Windows Scripting Host 5.6 for Windows 9x/NT/ME site:microsoft.com.
11. Microsoft Windows Script 5.6 Documentation site:microsoft.com.
12. WQL Keywords and description site:msdn.microsoft.com.
13. Windows Management Instrumentation site:msdn.microsoft.com.
14. Вы всё ещё не используете WMI? Часть 1 site:samag.ru.
15. Вы всё ещё не используете WMI? Часть 2 site:samag.ru.
Прочитано: 13 441
Windows Management Instrumentation (WMI) — это базовая технология как для управления так и для слежения за работой платформы Windows.
Только пользователи локальной группы «Администраторы» имеют право запускать WMIC.
В основе структуры данных в WBEM лежит Common Information Model (CIM), реализующая объектно-ориентированный подход к представлению компонентов системы. CIM является расширяемой моделью, что позволяет программам, системам и драйверам добавлять в неё свои классы, объекты, методы и свойства.
Важной особенностью WMI является то, что хранящиеся в нём объекты соответствуют динамическим ресурсам, то есть параметры этих ресурсов постоянно меняются, поэтому параметры таких объектов не хранятся постоянно, а создаются по запросу потребителя данных. Хранилище свойств объектов WMI называется репозиторием и расположено в системной папке операционной системы Windows:
%SystemRoot%\Windows\System32\wbem\Repository
Так как WMI построен по объектно-ориентированному принципу, то все данные операционной системы представлены в виде объектов и их свойств и методов.
Все классы группируются в пространства имен, которые иерархически упорядочены и логически связаны друг с другом по определенной технологии или области управления. В WMI имеется одно корневое пространство имен Root, которое в свою очередь имеет 4 подпространства: CIMv2, Default, Security и WMI.
Классы имеют свойства и методы и находятся в иерархической зависимости друг от друга, то есть классы-потомки могут наследовать или переопределять свойства классов-родителей, а также добавлять свои свойства.
Свойства классов используются для однозначной идентификации экземпляра класса и для описания состояния используемого ресурса. Обычно все свойства классов доступны только для чтения, хотя некоторые из них можно модифицировать определенным методом. Методы классов позволяют выполнить действия над управляемым ресурсом.
Каждому экземпляру класса можно обратиться по полному пути, который имеет следующую структуру:
[\\ComputerName\NameSpace][:ClassName][.KeyProperty1=Value1][,KeyProperty2=Value2]…]
где
ComputerName – имя компьютера
NameSpace – название пространства имен
ClassName – имя класса
KeyProperty1=Value1, KeyProperty2=Value2 – свойства объекта и значения, по
которому он идентифицируется.
Пример обращения к процессу с именем «Calc.exe», который запущен на локальной машине:
\\.\CIMv2:Win32_Process.Name=”Calc.exe”
Экземпляры классов могут генерировать события, к которым можно подписываться. При наступлении события WMI автоматически создает экземпляр того класса, которому соответствует это событие. Такой механизм удобно использовать для выполнения определенной команды при наступлении определенного события, то есть следить за состоянием объектов операционной системы.
Общая безопасность в WMI реализуется на уровне операционной системы, а дополнительная политика безопасности основана на уровнях пространств имен и протокола DCOM. То есть если пользователь не имеет права делать какое-то действие через операционную систему, он не сможет это сделать и через WMI. Если же пользователю дано какое-то право в операционной системе, то это ещё не означает, что это право будет и в WMI, так как в WMI действуют дополнительные параметры безопасности на уровне пространств имен.
Для вызова удаленных процедур WMI использует модель DCOM. В случае если возникает ошибка “Dcom Access Denied” то действия будут следующими: меня “Выполнить”->”dcomcnfg”->”Службы компонентов(Component Services)->Компьютеры->Мой компьютер->Свойства(правая кнопка мыши)->вкладка Безопасность COM Уровни олицетворения могут принимать следующие значения:
Anonymous | Анонимный | WMI-объект не может получить информацию о пользователе — доступ по такому типу не предоставляется |
Identify | Идентификация | WMI-объект запрашивает маркер доступа пользователя — доступ предоставляется только локально |
Impersonate | Олицетворение | WMI-объект имеет такие же права, какие имеет пользователь — рекомендуемый уровень для выполнения команд на удаленном компьютере |
Delegate | Делегирование | WMI-объект может обратиться от имени пользователя к другому WMI-объекту — нерекомендуемый уровень, так как команды можно выполнять удаленно через цепочку из нескольких компьютеров |
Уровни аутентификации (подлинности) могут принимать следующие значения:
None | Отсутствует | Проверка подлинности отсутствует |
Default | По умолчанию | Стандартные настройки безопасности, которые задаются компьютером-целью команды |
Connect | Подключение | Проверка только во время подключения к компьютеру-цели команды, проверка в ходе работы отсутствует |
Call | Вызов | Проверка подлинности при каждом запросе к компьютеру-цели команды, заголовки пакетов подписываются, но содержимое не шифруется |
Pkt | Пакет | Проверка подлинности всех пакетов к компьютеру-цели команды, заголовки пакетов подписываются, но содержимое не шифруется |
PktIntegrity | Целостность пакета | Проверка подлинности и целостности всех пакетов к компьютеру-цели команды, заголовки пакетов подписываются, но содержимое не шифруется |
PktPrivacy | Секретность пакета | Проверка подлинности и целостности всех пакетов к компьютеру-цели команды, заголовки и содержимое пакетов подписываются и шифруются |
wmimgmt.msc — оснастка консоли управления MMC для настройки WMI на локальном компьютере.
winmgmt.exe — консольная утилита управления WMI локального компьютера.
wbemtest.exe — графическая утилита для взаимодействия со структурой WMI на локальном или удаленном компьютере.
wmic.exe — консольная утилита для взаимодействия со структурой WMI на локальном компьютере.
mofcomp.exe — компилятор MOF-файлов для расширения структуры WMI, управления библиотекой классов WMI и восстановления репозитория.
Сейчас я покажу практические примеры используемые в моей повседневной работе:
Удаление больших файлов с расширением .log
wmic datafile where “drive=’с:’ and Extension=’.log’ and FileSize>’100000′” call delete
Список заблокированный учетных записей(вывод в файл на диске с:)
Wmic /output:”c:\useraccount.html” useraccount where (Status=’Degraded’) list full /format:htable
Определение архитектуры (Как пример на Server 2008)
wmic OS get OSArchitecture
Определяет тип сервера (Server 2008)
Команда возвращает числовое значение. Для Windows 2008 Server они следующие:
7 = Windows Server 2008 Standard Edition (full installation)
8 = Windows Server 2008 Datacenter Edition (full installation
10 = Windows Server 2008 Enterprise Edition (full installation)
12 = Windows Server 2008 Datacenter Edition (core installation)
13 = Windows Server 2008 Standard Edition (core installation)
14 = Windows Server 2008 Enterprise Edition (core installation)
42 = Hyper-V Server 2008
wmic OS get OperatingSystemSKU
Как подключаться удаленным системам.
/node:<имя_компа>
/user:<имя_пользователя>
/pass:<пасс_пользователя>
Завершить процесс по названию.
wmic.exe process where name=”calc.exe” delete
Wmic process where (caption=”notepad.exe”) call terminate
Получить более подробную справку по запуску команд.
process call /?:full
Если необходимо получить сведения о службе оповещения на компьютере
/node:<имя_компьютера> service where name=”alerter” list
Вывод сведений на экран
process where (name=”explorer.exe”) get caption,commandline,handle
Чтобы представить вывод в файл в табличном режиме
/output:c:\table.htm process get /format:htable
path win32_process.name=”explorer.exe” get caption,commandline,handle
При соединении с удалёнными системами можно брать имена компьютеров из текстового файла (server1,server2,server3)
/node:@c:\nodes.txt
context
Сохранение во внешнем XML-файле историю запускаемых в текущей сессии wmic-команд и результаты их выполнения.
/record:c:\outwmic.xml
Чтобы запустить новый процесс
process call create cmd.exe
Подключение к другому компьютеру возможно ещё так
/node:server /user:test /password:”password”
/node:<ip_address>
/user:Domain\name
Чтобы перезагрузить компьютер
/privileges:enable
/node:user os where (csname=”user”) call win32shutdown 2
Чтобы выключить компьютер
/node:user os where (csname=”user) call win32shutdown 1
Вывод свойств операционной системы
os get /value
Вывод информация о состоянии всех зарегистрированных служб на компьютерах server1, server2, server3
/node:server1,server2,server3 /output:c:\service.htm service get name,displayname,state /format:htable
Запуск и остановка служб
/node:server1 service where (name=”squid.exe”) call startservice
Принудительно выключить компьютер
wmic os where primary=”TRUE” call win32shutdown 6
\\FORD-POLL\ROOT\CIMV2:Win32_OperatingSystem.Name=”Microsoft Windows XP Professional|C:\\WINDOWS|\\Device\\Harddisk0\\Partition1″
Для того чтобы запустить сервис надо (вывести список сервисов в системе)
service list brief
service where (name=”<имя_сервиса>”) call startservice || stopservice
/output:c:\service.html service list full /format:htable
Чтобы работало wmic, надо
Служба WMI должна быть помещена в автозапуск, а также должно быть разрешено соединение по DCOM:
1) В разделе реестра HKLM\SOFTWARE\MICROSOFT\OLE установите значение EnableDCOM в “Y”, а также EnableRemoteConnect в “Y”. Значение EnableRemoteConnect по умолчанию “N”.
2) В разделе реестра \HKLM\SOFTWARE\Microsoft\wbem\cimom установите значение AutostartWin9X в “2”. Установите значение EnableAnonConnections в “1”.
3) Добавьте файл Winmgmt.exe в автозагрузку. Файл находится в каталоге \Windows\WBEM.
Модели DCOM сопоставлен TCP-порт 135.
netsh firewall add portopening TCP 135 DCOM_TCP135
Удаленно включаем службу удаленный рабочий стол (Remote Desktop)
Wmic /node:”servername” /user:”user@domain” /password:”password” RDToggle where ServerName=”server name” call SetAllowTSConnections 1
Вывод служб которые запускают с правами LocalSystem
/output:c:\id\cns.html service where startname=”LocalSystem” get Caption,name,started
Список шар на локальном машине
wmic share get caption,name,path
Перечисление всех путей к папкам из которых запущены программы
wmic.exe process get “ExecutablePath”, “ProcessID”
Драйверы в системе возможно останавливать или запускать например:
net stop beep
net start beep
sc stop beep
sc start beep
wmic sysdriver where name=’beep’ call PauseService
методы класса Win32_SystemDriver
StartService -> запускает службу или драйвер
StopService -> останавливает службу или драйвер
PauseService -> переводит службу или драйвер в состояние паузы
ResumeService -> восстанавливает состояние драйвера или службы
InterrogateService -> заставляет службу или драйвер обновить своё состояние в SCM
UserControlService -> позволяет послать службе или драйверу пользовательское сообщение.
Create -> создаёт новую службу или драйвер
Change -> изменяет службы или драйвер
ChangeStartMode -> изменяет режим запуска службы или драйвера
Delete -> удаляет службу или драйвер
Выключаем локальную машину.
ping -n seconds 127.0.0.1>nul&wmic OS WHERE Primary=”TRUE” CALL Win32Shutdown 6
где seconds – желаемое число секунд +1; Win32Shutdown 6 – 6 = 2 (reboot) + 4 (force). Никакого видимого сообщения о перезагрузке выведено не будет.
Полезные информационные сборки параметров.
wmic computersystem get domain, EnableDaylightSavingsTime, Manufacturer, Model, PartOfDomain, TotalPhysicalMemory, username
wmic bios get Caption, Manufacturer, SMBIOSBIOSVersion, Version
wmic baseboard get Manufacturer, Model, Product, SerialNumber, Version
wmic cpu get deviceID, Addresswidth, MaxClockSpeed, Name, Manufacturer, ProcessorID
wmic logicaldisk where drivetype=3 get name, freespace, systemname, filesystem, size, volumeserialnumber
drivetype::
= 1 NoRootDirectory The drive does not have a root directory.
= 2 Removable The drive is a removable storage device, such as a floppy disk drive or a USB flash drive.
= 3 Fixed The drive is a fixed disk.
= 4 Network The drive is a network drive.
= 5 CDRom The drive is an optical disc device, such as a CD or DVD-ROM.
= 6 Ram The drive is a RAM disk.
Задание приоритета процессору
wmic process where “name=’notepad.exe’” call setpriority 64
Выполнение команд через wmic
просто вставляем в командную строку
wmic process call create ‘cmd.exe /c ping 10.30.10.101’
Прописываем DNS-суффиксы удаленно
wmic /node: /failfast:on nicconfig call SetDNSSuffixSearchOrder (ford-i.ru,tc-toyota.local,lexus.local)
Прописываем DNS-сервера
nicconfig where index=8 call setdnsserversearchorder (“10.30.5.2″,”10.30.5.3”)
,где index= указывает номер интерфейса в системе на котором у вас поднята сеть
Команды загружаемые при входе системы
wmic startup list full && system
wmic:root\cli>/output:c:\startup_full.html startup list full /format:htable
wmic:root\cli>/output:c:\startup_system.html startup list system /format:htable
Наверняка еще с незапамятных времен, в операционной системе Windows, вам приходилось сталкиваться с аббревиатурой WMI? Это не что иное, как инструментарий управления Windows. Многие специалисты (и пользователи) встречаются с WMI довольно редко, но когда приходится работать с большими и важными корпоративными продуктами, тут уже WMI приобретает я бы сказал ключевое значение, поэтому устранение сбоев в работе WMI является важнейшим фактором работоспособности ключевых компонентов системы. Понятное дело, что информации о WMI превеликое множество, по нему пишутся увесистые серьезные труды на несколько сот страниц мелкого неразборчивого текста, но вся информация, которая необходима мне в данный момент времени, содержится в этой заметке.
Windows Management Instrumentation (WMI) — инструментарий управления Windows, механизм [централизованного] управления и наблюдения за функционированием многочисленных (программных и аппаратных) компонентов компьютерной инфраструктуры под управлением операционной системы Windows.
С момента своего появления в Windows95 OSR2, WMI остается основным механизмом управления для всех пользовательских/серверных операционных систем линейки Windows. Фактически WMI делает доступным создание управляющих приложений (скриптов), целью которых является взаимодействие (сбор информации/управление) с многочисленными, разнородными ресурсами системы Windows. Со временем технология WMI активно развивалась и стала основой для создания серьёзных корпоративных продуктов, таких как Configuration Manager. WMI изначально является расширенной и адаптированной под Windows реализацией промышленного стандарта WBEM:
Web-Based Enterprise Management (WBEM) — модель управления [предприятием] на базе web-стандартов (иначе: при помощи Интернет).
В разработке WBEM участвовал ряд крупных компаний, ставивших своей целью разработку стандартов управления производственной информационной средой, обеспечивающих координацию работы всех физических и логических компонентов [этой среды] из единой точки [управления], не зависящих от типа оборудования, сетевой инфраструктуры, операционной системы и множества других нюансов (стандартизация). Для этого была предложена общая информационная модель (Common Information Model, CIM), служащая для [схематичного] представления физической и логической структуры любого управляемого компонента [на предприятии] в виде масштабируемой объектно-ориентированной информационной модели и описывающая интерфейсы доступа к данным.
Масштабируемость (расширяемость) модели CIM призвана обеспечить [системам/драйверам/приложениям] добавление собственных классов, объектов, методов и свойств.
А поскольку WMI базируется на CIM, то её можно считать открытой унифицированной системой интерфейсов доступа к множеству [контролируемых] параметров, имеющихся у разнородных (аппаратных/программных) компонентов, функционирующих под управлением операционной системы Windows.
Достаточно уже определений, всё же хотелось бы понять, какое это имеет практическое обоснование? Давайте представим себе [абстрактную] ситуацию: возьмем системного администратора Васю Пупкина из первой половины 90-х годов, сервера у него на какой-нибудь версии Windows NT, клиенты вообще не пойми на чём. Внезапно (внезапность вообще частый спутник нашего брата возникает мысль: хорошо бы знать, на скольких моих машинках установлена Windows95 OSR2, из отобранных систем выделить работающие с 8Мб ОЗУ (и больше) и собранные на матерях Zida 5DXP (Tomato Board), на каких из полученных систем BIOS версии младше 1.90? И это не самый сложный запрос, согласитесь. И как предлагаете эту самую задачу администратору Васе решать? Естественно, что решения подобных задач были в то время нетривиальны, ведь данные разнообразных компонентов ОС всегда хранились во множестве источников: база пользователей SAM, журнал событий Event Log, системный реестр, файловая система. Доступ к этим источникам осуществлялся с помощью многочисленных утилит (диспетчер пользователей, просмотрщик журнала событий, редактор реестра), и хорошо если этот инструментарий был доступен непосредственно в ОС, а ведь часто имелся лишь API и для доступа к информации приходилось вообще писать что-то своё!! Сколько же времени уходило на решение подобных задач? В общем, администратор для решения схожих задач должен был осваивать большое количество разнообразных техник и приемов. Способствовало ли это возникновению запроса на разработку некоего стандартизованного доступа к разнородным данным компонентов операционной системы?! Вопрос, конечно же, риторический.
WMI обеспечивает решение разнообразных задач управления: например, проведение инвентаризации оборудования и программного обеспечения, мониторинг работы процессов и служб и множество аналогичных.
WMI представляет собой непротиворечивую и расширяемую объектную модель представления широкого спектра объектов (ресурсов): аппаратные/логические устройства, исполняемые процессы, файловая система, реестр, приложения, базы данных и многое многое другое.
WMI построена по объектно-ориентированному принципу, то есть в ней большинство данных, связанных с разнообразными компонентами операционной системы, представлены в виде объектов, их свойств (атрибутов, характеристик объекта) и методов (действий на объектом).
И для тех, кто пока еще слабо разбирается в объектно-ориентированном программировании, скажу что объект (или экземпляр класса) — сложноструктурированное представление информации, которое полностью описывает некую сущность в ОС. Класс — это модель объекта, некое абстрактное понятие, своеобразный «чертеж», содержащий описательную часть, на основе которой затем создаются объекты. Класс описывает свойства и методы, доступные у создаваемых впоследствии по этому описанию объектов. WMI поддерживает запросы от управляющих приложений на следующие операции:
- получение/изменение элементов данных (свойств) управляемых объектов.
- вызов методов управляемых объектов (действий над управляемыми объектами).
- выполнение запросов к набору данных управляемых объектов.
- регистрация для получения событий от управляемых объектов.
Инфраструктура WMI
WMI представляет собой уровень абстракции между приложениями и сценариями управления с одной стороны, и управляемыми ими физическими и логическими ресурсами с другой. Выражаясь иначе, WMI должна обеспечивать связь управляющих программ с управляемыми объектами, и обеспечивает она это при помощи следующих компонентов.
Служба/сервис WMI
В системе за всё это отвечает компонент под названием Менеджер объектов CIM (Common Information Model Object Manager, CIMOM), занимающийся обслуживанием взаимодействия управляющих приложений с WMI-провайдерами и управлением хранилищем базы данных WMI (репозиторием). Традиционно, как и большинство подобного функционала, CIMOM реализован в системе в виде службы, которая в данном конкретном случае носит название Инструментарий управления Windows. Исполняемый модуль, содержащий весь функционал (функции CIMOM) службы WMI, именуется winmgmt.exe и размещается в директории %SystemRoot%\System32\Wbem\. В разных версиях операционной системы Windows служба WMI запускалась по-разному:
Версия | Метод запуска |
---|---|
Windows 2000- | Менеджер запускался в качестве отдельной службы Windows. При таком способе WMI-провайдеры загружались в единое адресное пространство процесса, таким образом при падении одного провайдера мог завалиться весь процесс целиком. Вдобавок это порождало проблемы безопасности. |
Windows XP |
Все компоненты службы WMI запускаются в контексте общего хоста служб SVCHOST .
|
Windows Vista+ | Усовершенствована изоляция процессов путем загрузки провайдеров WMI в один или несколько экземпляров WMIPrvse.exe. Доработки в стабильности и безопасности WMI, включая задание уровней изоляции процессов, контекста безопасности, лимита ресурсов для провайдеров WMI. |
CIMOM запускается в контексте общего хоста служб (svchost), но может быть и запущен в качестве отдельного процесса. Провайдеры WMI должны быть зарегистрированы при помощи CIMOM для корректного перенаправления запросов от конечного (управляющего) приложения к целевому провайдеру. В дополнение ко всему, для доступа к WMI из сценариев, в системе присутствует библиотека поддержки сценариев WMI (WMI scripting library), которая располагается в файле wbemdisp.dll. Параметры конфигурации сервиса WMI представлены в ключе реестра:
- HKEY_LOCAL_MACHINE\Software\Microsoft\WBEM
WMI предоставляет доступ к собственным ресурсам через программный интерфейс компонентной объектной модели (COM API).
Провайдеры WMI
Когда управляющему приложению требуется получить какую-либо информацию от управляемых системных ресурсов, служба WMI (Winmgmt) должна иметь четкое представление (понимать) как работать с тем или иным запрашиваемым ресурсом, за это сопряжение ответственны так называемые провайдеры (поставщики) WMI.
Таким образом, WMI-провайдеры обеспечивают связь между менеджером объектов CIM и управляемыми ресурсами.
Из этого следует, что фактически провайдеры WMI маскируют [собой] детали внутренней реализации управляемых ими объектов, позволяя CIMOM взаимодействовать с подконтрольными провайдерам объектами единообразно, используя WMI API. Для лучшего понимания механизма можно провести аналогию между WMI-провайдерами и драйверами устройств: они так же обеспечивают взаимодействие с аппаратным или программным ресурсом (или набором ресурсов). Провайдеры (поставщики) являются основой WMI, поскольку:
Практически все классы WMI и соответствующие им методы реализованы посредством провайдеров WMI.
Провайдеры WMI обычно представлены в системе в виде пары файлов:
- MOF-файла, определяющего классы событий/данных (для которых данные будут предоставляться);
- исполняемого модуля (формата DLL/EXE/***-файла), содержащего код, обеспечивающий весь процесс обработки/предоставления данных;
Выбор файла-контейнера для хранения кода достаточно широкий, поскольку любое приложение в системе (включая и драйвера) теоретически может функционировать в качестве провайдера (поставщика) WMI и создавать собственные классы WMI. Тем не менее, код провайдеров чаще представляется следующими методами:
- в качестве динамических библиотек (COM DLL) пользовательского режима;
- в качестве драйверов режима ядра;
Каждый WMI-провайдер имеет собственные идентификаторы CLSID, зарегистрированные в системном реестре и ассоциированные с ним для дальнейшего разрешения COM. Данный CLSID используется для поиска соответствующей библиотеки (DLL), реализующей весь функционал провайдера. WMI провайдер собирает данные: например, при запросе списка процессов — опрашивает все работающие/запущенные в системе процессы, при работе с реестром — перечисляет ключи реестра, и так далее.
Классически провайдеры реализуются в виде COM/DCOM-серверов, представленных в виде библиотек (DLL), обычно располагающихся в каталоге %SystemRoot%\System32\Wbem\.
В то время как служба WMI обслуживает управляющие приложения через COM-интерфейс, WMI-провайдеры действуют в качестве COM-серверов, обрабатывающих запросы от службы WMI. Когда провайдер загружается, он регистрирует собственное положение и классы, объекты, свойства, методы и события, которые он предоставляет [в WMI]. WMI использует эту информацию для перенаправления запросов к соответствующему провайдеру. Так же взаимодействие между разными участниками WMI может происходить:
- локально — через COM-интерфейс;
- удаленно — через DCOM-интерфейс или [более современный] Windows Remote Management (WinRM).
WMI обрабатывает запросы от управляющих приложений следующим образом:
- [Управляющее] приложение отправляет запрос к WMI, которая, в свою очередь, перенаправляет его к соответствующему провайдеру (поставщику).
- Провайдер выполняет взаимодействие с запрошенным системным ресурсом и возвращает результат к WMI.
- WMI передает ответ [обратно] к вызвавшему приложению. Ответ может быть актуальными данными [запрашиваемого] ресурса или результатом выполнения [требуемой] операции.
Microsoft предлагает некоторое количество «встроенных» провайдеров в составе дистрибутива операционной системы Windows: журнала событий, системного реестра, файловой системы и некоторых других.
Репозиторий (хранилище)
Как было сказано выше, WMI базируется на том, что информация о состоянии любого управляемого объекта может быть представлена в виде общей информационной модели (CIM), которая сама по себе фактически и является хранилищем объектов и классов, моделирующих различные компоненты компьютерной системы. Таким образом, в общем случае:
Репозиторий CIM — хранилище модели CIM.
или более адаптированно для реалий операционной системы:
WMI (CIM) Репозиторий — это дисковая база данных, используемая для хранения «откомпилированного представления» объектов WMI (определений классов и экземпляров пространств имен) и обеспечивающая эффективный (оптимизированный) доступ к ним.
Где класс выступает в качестве модели (шаблона) управляемого объекта (фактически любого компонента операционной системы: процесса, сервиса, файловой системы, события, диска и многого другого). В файловой системе репозиторий располагается по пути: %SystemRoot%\System32\Wbem\Repository\ и состоит из следующих файлов (для Windows 7):
Имя | Описание |
---|---|
index.btr | Индекс (индексный файл, словарь), содержащий ключи и адреса записей в файле данных (objects.data). Содержит индекс Би-дерева, используемым для поиска CIM-записей в файле objects.data. Ключи в индексе являются ASCII-строками, которые содержат хеш данных [фиксированной длины]. Когда необходимо извлечь объект из objects.data, используется индекс для быстрого поиска смещения. |
mapping1.map mapping2.map mapping3.map |
Порядковый номер в заголовке каждого файла сопоставления помогает службе WMI выбрать активный файл сопоставления. [Активный] файл сопоставления определяет, как именно сопоставить номер страницы логических данных с номером страницы физических данных внутри файлов objects.data и index.btr. Без этих сопоставителей, невозможно корректно интерпретировать данные в файле objects.data. |
objects.data | Данные объектов. Собственно, сам репозиторий. Файл objects.data содержит CIM-записи в двоичном формате. В ранних версиях Windows репозиторий размещался в файле cim.rep. |
Данные в WMI могут быть двух типов:
- статические (откомпилированные) данные — доступны в определении класса или объекта и хранятся в репозитории WMI;
- динамические (формируемые в процессе) данные — доступны в виде ответа на запрос к WMI-провайдеру (создаются «на лету»). например, объекты Win32_Process, которые генерируются в ходе опроса дерева процессов.
Но чаще всего в модели CIM хранятся классы, которые соответствуют динамически изменяемым ресурсам, поэтому объекты-экземпляры таких классов создаются провайдером по запросу потребителя WMI и не хранятся постоянно в репозитории CIM, поскольку состояние большинства WMI-совместимых устройств меняется довольно быстро и непрерывное обновление информации в репозитории [CIM] может существенно влиять на производительность операционной системы.
В дополнение ко всему, в репозитории WMI хранится информация о безопасности WMI.
Судя по всему, WMI использует доработанную версию Microsoft Jet Database Engine для доступа к данным репозитория, поддерживающую вставку, удаление, поиск ключей и сопоставление по префиксу ключа (спасибо, кэп).
MOF
Спецификация CIM, помимо всего прочего, включает в себя описание языка, предназначенного для предоставления понятного человеку способа описания структур CIM. WMI использует так называемый формат управляемого объекта (MOF, Managed Object Format) в качестве языка, используемого для описания классов CIM.
MOF представляет собой язык (формат, способ) описания классов, экземпляров [классов] и иных структур CIM с использованием специализированных директив, описываемых в привычном для нас текстовом формате. Базируется на языке описания интерфейсов (Interface Definition Language, IDL).
MOF-файл содержит директивы, задающие: имена сущностей, которые могут быть запрошены, типы полей в сложных классах, и разрешения, связанные с группами объектов. Структуры подавляющего большинства объектов WMI описываются парой файлов следующих форматов:
- <имя_файла>.mof — общее описание объектов;
- <имя_файла>.mfl — локализованное описание объектов;
Данные, содержащиеся в файлах MOF при помощи специальных утилит компилируются и сохраняются в репозитории WMI. Например, mofcomp.exe фактически выполняет компиляцию/вставку данных, описанных в файлах MOF, в репозиторий CIM. Можно сказать, что MOF это фактически объектно-ориентированный язык, позволяющий описывать:
- Пространства имен — Классы
- Свойства
- Методы
- Квалификаторы
- Интерфейсы
- Ссылки
- Комментарии
Разработчик может создавать собственные классы [данных], предоставляющие данные, доступные через уже имеющиеся в системе провайдеры WMI, такие (например) как данные системного реестра. В этих случаях, администратор должен импортировать сторонние mof-файлы. Например, файл провайдера SMS smsprov.mof содержит определения [на MOF-языке], описывающие пространство имен Root\SMS
и содержащиеся в нем классы. MOF использует синтаксис C++ и предоставляет [своеобразный] шаблон для описания WMI-объекта. В то время, как WMI-провайдеры генерируют неструктурированные данные, MOF-файлы представляют шаблоны, в которых сгенерированные данные форматированы.
Классы и пространства имен WMI
Классы WMI сгруппированы в пространства имен (namespaces), которые выстроены иерархически в виде дерева (с единым корнем) и напоминают используемые в традиционных объектно-ориентированных языках программирования.
Пространство имен WMI – это группировка (контейнер) классов и объектов, объединенных по назначению, то есть относящихся к определенной технологии или области управления.
Вне зависимости от версии WMI в системе имеется несколько предопределенных пространств — корневое пространство имён Root, и 4 пространства, располагающихся уровнем ниже: CIMv2
, Default
, Security
и WMI
. Все пространства имен являются производными от КОРНЕВОГО (Root) пространства имен. Пространства имен организуют в себе классы WMI и другие элементы, таким образом их проще представить себе в качестве контейнера или каталога файловой системы. Некоторые пространства имен содержат вложенные пространства имен, и так далее. Классы объектов WMI распределены иерархически в пространства имен, похожих на используемые в традиционных объектно-ориентированных языках программирования. Одно из существующих в Windows пространств имен назначается пространством по умолчанию, в стандартной поставке им является пространство имен Root\CIMV2. Таким образом, при запросах объектов, в которых явно не задано пространство имен, будем выбрано пространство по умолчанию.
Язык запросов WMI (WQL)
Очевидно было бы крайне неудобно ограничивать доступ из управляющих приложений (потребителей WMI) к управляемым объектам лишь функциями WMI API (доступного исключительно из кода приложений), гораздо универсальнее создать специализированный удобочитаемый язык запросов, который может быть использован в различного вида инструментарии (программах/консолях). Для этой цели был разработан Язык запросов WMI:
WMI Query Language (WQL) — язык запросов, предоставляющий простой синтаксис для обращения к экземплярам объектов, классам и пространствам имен WMI. С использованием подобных запросов и происходит обращение потребителей (управляющих приложений) WMI к управляемым объектам WMI. WQL, в свою очередь, является Microsoft-адаптацией языка запросов CIM (CIM Query Language, CQL).
Тем не менее не все провайдеры управляемого объекта поддерживают WQL, в подобных ситуациях менеджер объектов CIM должен преобразовать запрос к виду, обрабатываемому [конкретным] провайдером. WQL представляет собой специально сконструированные запросы, которые являются подмножеством (подвидом) SQL. Концептуальное отличие от ANSI SQL — это отсутствие инструкций для изменения данных, то есть при помощи WQL возможна лишь выборка данных с помощью команды SELECT
. Помимо ограничений на работу с объектами, WQL не поддерживает такие операторы как DISTINCT
, JOIN
, ORDER
, GROUP
, математические функции, а конструкции IS и NOT IS применяются только в сочетании с константой NULL. WQL запросы можно протестировать при помощи GUI-утилиты wbemtest и CUI-утилиты wmic (утилита wmic не требует указания ключевого слова SELECT и полей выборки), а затем применять их в собственных скриптах.
Права доступа к пространствам имен
Механизм безопасности действует в WMI на уровне пространств имен. Для каждого пространства может быть определен собственный дескриптор безопасности, содержащий таблицу контроля доступа. Каждая запись таблицы контроля доступа содержит информацию о том, какие права (разрешения) имеет [тот или иной] пользователь при выполнении операций в данном пространстве имен. Несмотря на то, что пространства имен расположены по идентичному пути, то есть имеют единый корень, привилегии отличны для каждого пространства имен, и поэтому разрешения дочернего пространства имен не наследуются от родительского. Чтобы проверить/назначить разрешения WMI, выполните следующие действия:
- Пуск → Администрирование и выберите пункт Управление компьютером;
- Разверните узел Службы и приложения и щелкните правой кнопкой мыши элемент управления WMI;
- Правая кнопка мыши → выберите пункт меню Свойства, чтобы открыть диалоговое окно Свойства элемента управления WMI;
- Перейдите на вкладку Безопасность и разверните корневой узел Root. Выберите требуемый объект пространства имен (установив курсор), затем нажмите кнопку Безопасность;
Отладка/запись событий WMI
Похоже в ранних реализациях настройка журнала событий WMI находилась в свойствах элемента управления WMI, однако в новых версиях её перенесли в общий Просмотр событий.
- Открыть Просмотр Событий (Event Viewer, Eventvwr).
- В меню Вид, выбрать Отобразить аналитический и отладочный журналы.
- В дереве в левом фрейме разворачиваем пункт Журналы приложений и служб (Applications and Service Logs) → Microsoft → Windows → WMI Activity
- Правую кнопку мыши на пункте Trace и выбираем Включить журнал (Enable Log). Если выбрать Свойства из того же меню, то можно увидеть куда пишутся события трассировки: %SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-WMI-Activity%4Trace.etl.
Инструменты для взаимодействия с WMI
Наименование | Назначение |
---|---|
wmimgmt.msc | Оснастка консоли управления [MMC] для настройки WMI (локальная система). |
winmgmt.exe | Консольная утилита управления WMI (локальная система). |
wbemtest.exe | Утилита [с графическим интерфейсом] для взаимодействия с инфраструктурой WMI: подключение к пространству имен, выполнения операций (локальная/удаленная система). |
wmic.exe | Консольная утилита для взаимодействия со структурой WMI (локальная/удаленная система). |
wmidiag.vbs | Утилита (скрипт) диагностики WMI, разработанный MS. На данный момент недоступна на официальном сайте MS, поскольку некоторые версии WMIDiag корректно работали только с определенными версиями ОС Windows. |
mofcomp.exe | Компилятор MOF-файлов. Выполняет анализ директив (инструкций) MOF-файла и добавление определенных там классов/экземпляров классов в репозиторий WMI (локальная система). |
Windows Scripting Host (WSH) | в Windows представлены два языка, базирующихся на WSH: VBScript и JScript. Несмотря на то, что эти языки [морально] устарели, оба всё еще остаются мощными скриптовыми языками, прекрасно решающими задачи по взаимодействию с WMI. |
Powershell | Язык сценариев от разработчиков. |
winrm.exe | Консольная утилита для удаленного управления Windows. Может быть использована для перечисления экземпляров объектов WMI, вызова методов, создания/удаления экземпляров объектов посредством службы WinRM (локальная/удаленная система). При помощи утилиты можно задавать параметры сервиса WinRM. |
C/C++ | Есть возможность взаимодействовать с WMI с помощью «неуправляемого» кода, написанного на C/C++, для этого используется Component Object Model (COM) API для WMI. Для этого существует набор интерфейсов IWbem* и некоторых других. |
.NET | Библиотека классов .NET предоставляет несколько WMI классов в рамках пространства имен System.Management, взаимодействующих с WMI в языках C#, VB.Net, and F#. |
Ошибки WMI
Причиной зачастую бывает падение службы WMI, что может повлечь за собой повреждение репозитория со всеми вытекающими. Поэтому:
Если репозиторий имеет те или иные повреждения, то служба WMI нормально функционировать не будет.
Ну а последствия неправильного функционирования службы WMI в системе следующие:
- отказ в запуске [зависимых от WMI] системных служб;
- отказ в установке/запуске приложений [зависимых от WMI];
- некорректная работа объектов групповых политик;
- ошибки при выполнении скриптов [использующих WMI];
Более осязаемые проявления проблем с сервисом/репозиторием WMI:
- Ошибки в log-файлах самих приложений: WBEM_E_NOT_FOUND — 0x80041002.
- Ошибки отказа при подключении к пространствам имен
Root\Default
илиRoot\cimv2
; - Ошибка/подвисание при открытии свойств WMI в оснастке Управление компьютером: «WMI : Not Found», «0x80041010 WBEM_E_INVALID_CLASS», «Filed to initialize all required WMI classes»;
- Подвисание разных утилит по работе с WMI (wbemtest и прч);
- Отсутствие в репозитории некоторых схем/классов/объектов;
- Проблема в запуске SCCM-агента (WBEM_E_INVALID_CLASS — 0x80041010);
- Ошибки подключения/операций (0x8007054e);
- Ошибки подгрузки WMI-провайдеров: WBEM_E_PROVIDER_LOAD_FAILURE — 0x80041013;
- Ошибки доступа при попытке доступа к WMI-объектам: E_ACCESS_DENIED — 0x80070005;
- Ошибки поиска пространств имен: WBEM_E_INVALID_NAMESPACE — 0x8004100E;
- Ошибки в Журнале событий Windows (Приложение) — источник WinMgmt, EventID — 10;
Восстановление WMI
Доступный на данный момент в системе/Сети инструментарий диагностических инструментов WMI даёт возможность довольно скрупулезно подойти в вопросу восстановления работоспособности WMI, но кто бы еще так же детально (тонко) этот WMI понимал, так что процесс этот довольно трудоемкий. Поэтому поступают проще и обычно используют основные методы:
- Набор действий по восстановлению репозитория через утилиты командной строки;
- [многочисленные] скрипты по восстановлению репозитория/перекомпиляции mof/mfl, перерегистрации провайдеров;
Эти методики подходят для большинства ситуаций, которые могут встретиться на рабочих станциях пользователей/серверах. Тем не менее, имеется несколько тонких моментов в логике восстановления работоспособности WMI, и их нужно непременно усвоить:
- Самым примитивным способом восстановления репозитория является удаление/переименование его рабочей директории. То есть, вы переименовываете директорию %SystemRoot%\System32\Wbem\Repository, к примеру, в Repository.old и ждете. После определенного таймаута сервис определит отсутствие директории репозитория и запустит процедуру восстановления. Но этот простой способ особенно никем не применяется, поскольку не учитывает перекомпиляцию не входящих в автовосстановление (список .mof в реестре) классов и не выполняет перерегистрацию провайдеров.
- Вне зависимости от того, где и как оно применяется, удаление рабочего WMI-репозитория является достаточно разрушительной операцией, которая может повлечь за собой потерю данных, возникновение ошибок в WMI-приложениях, замедление отклика некоторых операций, и возникновении других, сложнодиагностируемых проблем.
- Существуют приложения, которые в процессе установки в систему [самостоятельно] напрямую обновляют репозиторий, вообще не используя никаких .mof-файлов. Соответственно, при пересоздании (удалении и создании) репозитория подобные приложения не имеют возможности обновить базу данных и их данные, связанные с WMI, будут удалены (потеряны) вплоть до момента, пока вы не переустановите означенные приложения (в режиме восстановления).
- Следует помнить, что не все приложения хранят свои WMI-провайдеры (.dll) и .mof-файлы в %SystemRoot%\System32\wbem. Соответственно, вам нужно будет выявить подобные приложения (поиск по маске
*.mof
), и либо произвести их переустановку, либо выполнить ручную регистрацию провайдеров (библиотек) и перекомпиляцию .mof-файлов. - Существуют .mof-файлы, которые содержат директивы вида #pragma deleteclass или #pragma deleteinstance. По хорошему, некоторые источники советуют временно перемещать подобные файлы в стороннюю директорию перед потоковой перекомпиляцией всех .mof-файлов. Но никто этого делать не хочет, ну и мы не будем.
- [ начиная с Windows7 ] в каталоге репозитория можно обнаружить файлы, содержащие информацию об удалении, такие как OfflineFilesWmiProvider_Uninstall.mof, Wdf01000Uninstall.mof, Win32_EncryptableVolumeUninstall.mof, WinsatUninstall.mof, wpcuninst.mof, WsmAgentUninstall.mof, WUDFxUninstall.mof, в именах которых присутствует слово uninstall. И если скрипты перечисляют и компилируют все без исключения файлы, то компиляция подобных файлов приведет к удалению классов, соответственно последние станут недоступны. Но эту проблему можно обойти путем исключения.
- Перекомпиляция MOF-файлов зачастую должна производиться в определенной последовательности. Например, классы в файле [условно] 1.mof могут зависеть от классов, указанных в файле 2.mof. Если последние отсутствуют, утилита mofcomp.exe не будет добавлять классы. Для того, что бы подобрать правильную последовательность, нужно знать зависимости для всех классов, представленных в системе. Возможно эту проблему можно частично решить перекомпиляцией каких-то базовых (основных) .mof-файлов в первую очередь, перед основным циклом перекомпиляции всех остальных. Поэтому скрипты на данный момент не делают всё идеально, но все-равно даже это работает и приносит результат
- Везде встречаются рекомендации о том, что сперва надо компилировать .mof-файлы, а затем уже их локализованные .mfl-копии. Когда все файлы размещались в одной директории, было удобно, но в последних версиях ОС .mfl переехали в локализованные поддиректории (например, ru-RU), поэтому проход по *.mfl надо делать с учетом вложенных директорий?
- Имеются рекомендации, что в 64-битных ОС работу ручную перекомпиляцию репозитория надо выполнять из директории %SystemRoot%\SysWOW64\wbem, а на 32-битных системах из %SystemRoot%\System32\wbem, но оказалось, что (в ОС, начиная с Windows 7) в директории для 64-битной ОС отсутствуют многие .mof файлы, что меня лично настораживает. Рекомендация могла устареть? К тому же, большинство на это забивает и радуется
Поэтому вы уже поняли, что приведенные тут решения несовершенны, но в реальных боевых условиях не раз помогали избавиться от проблем с WMI (даже удивительно).
Метод 1
Самое правильное, это всегда начинать с наименее деструктивных техник работы с репозиторием, например с помощью входящей в состав дистрибутива утилиты winmgmt. Выполните следующую команду (начиная с Windows Vista/Server 2008):
winmgmt /verifyrepository
Если проверка вернула ошибку (например, WMI repository is INCONSISTENT), то выполняем перестроение репозитория:
winmmgmt /salvagerepository
Затем повторно проверяем репозиторий:
winmgmt /verifyrepository
Ну и если перестроение не дало результата и вы всё еще получаете ошибки, то можно воспользоваться более деструктивным методом (серия: остановка службы + сброс репозитория):
net stop winmgmt /y
winmgmt /resetrepository
Метод 2
Потенциально, приведенный в данном методе скрипт достаточно разрушителен, поскольку удаляет рабочий репозиторий. Тем не менее, при всех своих недостатках метод достаточно эффективен и не раз меня выручал. Следующий powershell-скрипт оптимизирован для использования под Windows 7 и выше, представляет собой последовательность действий по сохранению (в резервную папку) текущего репозитория, перестроению репозитория (перекомпиляции объектов), перерегистрации компонентных библиотек (провайдеров), а так же учитывает большинство описанных выше нюансов. Создайте файл resetWMI.ps1 и разместите там следующее содержимое:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# Установка текущей директорией %Windir%\System32\wbem $WBEM = «${Env:Windir}\System32\wbem» Set-Location -Path $WBEM # Остановка сервиса WMI $WMIService = Get-Service -Name «Winmgmt» $WMIService | Stop-Service -Force -Verbose Start-Sleep -seconds 1 # Переименование существующей директории репозитория if (Test-Path «$WBEM\Repository») { Write-Host «Renaming WBEM Repository…» if (Test-Path «$WBEM\repository.bak») { Remove-Item «$WBEM\repository.bak» -Force -Recurse -Confirm:$false } Rename-Item -Path «$WBEM\repository» -NewName «$WBEM\repository.bak» -Force } # Компиляции классов 1-го уровня вперед остальных & mofcomp cimwin32.mof & mofcomp cimwin32.mfl & mofcomp rsop.mof & mofcomp rsop.mfl & mofcomp wmi.mof & mofcomp wmi.mfl # Регистрация всех WMI-провайдеров Get-ChildItem -Path $WBEM -Filter «*.dll» | ForEach-Object { Start-Process regsvr32.exe -ArgumentList «/s»,«`»$_`»» -Passthru -Wait -NoNewWindow } # Регистрация всех WMI-провайдеров Get-ChildItem -Path $WBEM -Filter «*.exe» | Where-Object { ($_.Name -notmatch «wbemtest.exe») -and ($_.Name -notmatch «mofcomp.exe») -and ($_.Name -notmatch «wbemcntl.exe») } | ForEach-Object { Start-Process -FilePath $_.Fullname -ArgumentList «/RegServer» -Passthru -Wait -NoNewWindow } # Компиляция всех .mof Get-ChildItem -Path «$WBEM\*» -Include «*.mof» | Where-Object { $_.Name -notlike «*uninstall*» } | ForEach-Object { & mofcomp $_.FullName } # Компиляция всех .mfl Get-ChildItem -Path «$WBEM\*» -Recurse -Include «*.mfl» | Where-Object { $_.Name -notlike «*uninstall*» } | ForEach-Object { & mofcomp $_.FullName } # Запуск сервиса WMI $WMIService | Start-Service -Verbose |
скрипт можно сделать менее проблемным, если закомментировать группу инструкций (строки 10-15), которые производят переименование текущего репозитория.