Windows management instrumentation winmgmt на русском

На компьютере под управлением Windows 10 перестала работать WMI. Никакие скрипты, раньше нормально работавшие, теперь не функционируют. Диапазон возвращаемых ошибок достаточно велик: 0x80041XXX,

Я столкнулся с этой ситуацией на днях: мои студенты тестировали управление системными функциями и две машины в домене (на обеих – Windows 10) стали возвращать ошибки при работе с Windows Management Instrumentation. Основной админ ещё не вышел из отпуска, пришлось вспоминать, что я бывший руководитель Отдела ИТ :)

Сразу отвечу на третий вопрос: без рабочего WMI, на мой взгляд, можно оставлять лишь домашний игровой компьютер, на котором, кроме игр и просмотра видео, больше ничего не делается (разве что дети учатся программировать). В остальных случаях, особенно на корпоративных машинах, тем более в домене, WMI должна работать как часы. Это моё мнение, кто-то может не согласиться.

Теперь о причинах произошедшего: их может быть очень много. Забегая вперед, скажу что на одной машине это произошло из-за того, что на жестком диске закончилось место, а затем был сбой по питанию из-за сломанного ИБП (увы, никто не застрахован; сервера, конечно, защищены от подобного, а обычная рабочая машинка не была). На второй хуже: нефатальный сбой жесткого диска с последующим BSOD. В целом, разобраться с причинами не так уж и важно, главное, выяснить, что причиной не является вирус или попытка взлома. Впрочем, намеренное удаление или случайная порча системных файлов тоже должны быть рассмотрены достаточно пристально.

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

1 этап. Проверка работы сервиса.

Проверяем имеется ли в системе служба Windows Management Instrumentation (Winmgmt) и включена ли она. Вызываем Службы (в Windows 10 проще всего через Пуск/Средства администрирования/Службы, но я предпочитаю в любой версии Windows, кроме самых старых, напечатать в командной строке services.msc), ищем Инструментарий управления Windows/Windows Management Instrumentation, проверяем, запущена ли она:

введите сюда описание изображения

Если она не запущена, пытаемся запустить, выставим режим запуска в «Автоматически». Если запущена, пытаемся перезапустить (Остановить/запустить). После этого проверяем работоспособность WMI. Проще всего сделать это, выполнив любой WMI-запрос в powershell (напоминаю, что powershell в Windows 10 запускается через Пуск/Windows PowerShell/Windows Power Shell, но проще, на мой взгляд, запустить командную строку с админовскими правами, а в ней уже набрать powershell), например, такой: (вы можете выполнить другой, свой любимый :))

Get-WmiObject -List -ComputerName localhost

Если у вас вылетела портянка объектов, всё в порядке. Если же полезли ошибки, значит, работоспособность не восстановлена, переходим ко второму этапу.

Между делом скажу пару слов об официальной утилите Microsoft WMI Diagnosis. Все почему-то наперебой её рекомендуют, как хороший помощник при восстановлении. Увы, я убил достаточно много времени на анализ результатов действия этой утилиты: скрипт создал кучу лог-файлов, через которые продраться можно, если вы никуда не торопитесь, у вас есть куча времени и полкило пуэра/кофе-машина. В причинах сбоев я разобрался быстрее без неё. Вероятность того, что она может помочь непосредственно в скором восстановлении работы WMI – очень мала.

2 этап. Недеструктивное восстановление

Стоит попытаться вначале выполнить перерегистрацию библиотек и рекомпиляцию файлов расширения свойств объектов (Managed Object Format, MOF) и языковую составляющую этих файлов (MFL). Практически гарантированно сработает, если попытка WMI-запроса у вас вызывала ошибку вида “Ошибка в файле WMI.MOF” или любом другом MOF-файле. Для этого выполним следующие операции:

  1. Остановим службу WMI, обязательно запретив её автостарт
  2. Перерегистрируем все библиотеки в папке Windowssystem32wbem
  3. Перерегистрируем службы WMI и WMI Provider Host
  4. Запускаем службу WMI и разрешаем её автостарт
  5. Рекомпилируем MOF и MFL файлы

Можно собрать всё это в один BAT-файл и запустить:

# пункт 1
sc config winmgmt start= disabled
net stop winmgmt
# пункт 2
cd %windir%system32wbem
for /f %%s in ('dir /b *.dll') do regsvr32 /s %%s
#пункт 3
wmiprvse /regserver
winmgmt /regserver
#пункт 4
sc config winmgmt start= auto
net start winmgmt
#пункт 5
for /f %%s in ('dir /b *.mof') do mofcomp %%s
for /f %%s in ('dir /b *.mfl') do mofcomp %%s

Отмечу, что таким образом я восстановил работу WMI на первой машине. Со второй, увы не получилось. Если у вас не получается, пора переходить к 3му этапу

3 этап. Деструктивное восстановление

Фактически, на 3м этапе мы пересоздаем хранилище WMI, как таковое, которое находится в папке WindowsSystem32WbemRepository и является базой данных, в которой хранятся данные и определения стандартных WMI-классов и статическая информация дополнительных WMI-классов, если они создавались на вашей машине.

Перед операциями проверьте состояние жёсткого диска и файловой системы!!!

Проверяем целостность (На Windows XP и ниже не работает):

winmgmt /verifyrepository

В случае ответа отличного от “База данных WMI согласована”, можно выполнить «мягкое восстановление» командой:

winmgmt /salvagerepository

с последующим перезапуском службы:

net stop Winmgmt
net start Winmgmt

Если мягкое восстановление не помогло, пробуем вернуть хранилище в начальное состояние (последствия: все дополнительные классы WMI, когда-либо зарегистрированные в вашей системе, скорее всего, придётся регистрировать заново):

winmgmt /resetrepository

с последующим рестартом системы. Отмечу, что вторая машина заработала после этого этапа. Последствия были не сильно удручающими, но серьёзными: пришлось переинсталлировать Visual Studio и Delphi Starter, MS Office отказался работать и его пришлось деинсталлировать вручную, удаляя папки, файлы и записи из реестра, с последующей повторной установкой. Также слетели все наши собственные классы WMI.

Но, если и это не помогло, придётся удалять и создавать хранилище заново. Это можно сделать следующим BAT-файлом:

# Остановим службу WMI, обязательно запретив её автостарт
sc config winmgmt start= disabled
net stop winmgmt
# проводим реинициализацию WMI
cd %windir%system32wbem
winmgmt /kill
winmgmt /unregserver
winmgmt /regserver
winmgmt /resyncperf
# создаем на всякий случай резервную копию нашего хранилища в папку WMI_VicoNT_Backup
# у вас, разумеется, может быть другое имя папки
if exist WMI_VicoNT_Backup rd WMI_VicoNT_Backup /s /q
rename Repository Repos_bakup
# воссоздаем хранилище
regsvr32 /s %systemroot%system32scecli.dll
regsvr32 /s %systemroot%system32userenv.dll
for /f %%s in ('dir /b *.dll') do regsvr32 /s %%s
for /f %%s in ('dir /b *.mof') do mofcomp %%s
for /f %%s in ('dir /b *.mfl') do mofcomp %%s
# запускаем службу WMI, заново регистрируем WMI Provider Host
sc config winmgmt start= auto
net start winmgmt
wmiprvse /regserver

Перегружаем компьютер. Если и после этих действий 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%System32WBEMRepositoryFS

Так как WMI построен по объектно-ориентированному принципу, то все данные операционной системы представлены в виде объектов и их свойств и методов.

Все классы группируются в пространства имен, которые иерархически упорядочены и логически связаны друг с другом по определенной технологии или области управления. В WMI имеется одно корневое пространство имен Root, которое в свою очередь имеет 4 подпространства: CIMv2, Default, Secutiry и WMI.

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

Свойства классов используются для однозначной идентификации экземпляра класса и для описания состояния используемого ресурса. Обычно все свойства классов доступны только для чтения, хотя некоторые из них можно модифицировать определенным методом. Методы классов позволяют выполнить действия над управляемым ресурсом.

Каждому экземпляру класса можно обратиться по полному пути, который имеет следующую структуру:

[\ComputerNameNameSpace][: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 на локальном компьютере.

Administration via WMI - wmimgmt

Оснастка консоли управления MMC для настройки WMI

winmgmt.exe — консольная утилита управления WMI локального компьютера.

Administration via WMI - winmgmt

Консольная утилита управления WMI

wbemtest.exe — графическая утилита для взаимодействия со структурой WMI на локальном или удаленном компьютере.

Administration via WMI - wbemtest

Графическая утилита для взаимодействия со структурой WMI

wmic.exe — консольная утилита для взаимодействия со структурой WMI на локальном компьютере.

Administration via WMI - wmic

Консольная утилита для взаимодействия со структурой WMI

mofcomp.exe — компилятор MOF-файлов для расширения структуры WMI, управления библиотекой классов WMI и восстановления репозитория.

Administration via WMI - mofcomp

Компилятор 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(".", "RootCIMv2",,,,, 128)

Моникер — это строка, задающая путь к классу WMI, экземпляр которого должен быть создан. Моникер состоит из обязательного префикса «winmgmts:», необязательных настроек безопасности, необязательного пути к требуемому классу:

Set mSWbemServices = GetObject("winmgmts:[{SecurityOptions}!]\[Server][NameSpace]")

Пример использования моникера:

' Подключение к пространству имен по умолчанию локального компьютера
Set mSWbemServices0 = GetObject("winmgmts:")

' Подключение к указанному пространству имен удаленного компьютера
' с указанием метода олицетворения
Set mSWbemServices1 = GetObject("winmgmts:{impersonationLevel=Impersonate}!" & _
 "\MyComputerRootCIMv2")

' Подключение к указанному объекту локального компьютера
' с указанием метода олицетворения и привилегий
Set mSWbemServices2 = GetObject("winmgmts:" & _
 "{impersonationLevel=Impersonate, (Shutdown, RemoteShutdown)}!" & _
 "\.RootCIMv2:Win32Process.Handle=4")

' Подключение к указанному объекту локального компьютера
Set mSWbemServices3 = GetObject("winmgmts:\.RootCIMv2:Win32Process.Handle=4")

В результате подключения к WMI получается объект SWbemServices, который обладает определенными свойствами и методами. Наиболее часто используемые из них — это Get, ExecQuery, ExecMethod.

Метод Get используется для возвращения определения класса или экземпляра управляемого ресурса:

Set mObject = Get([ObjectPath],[Flags],[WbemNamedValueSet])
где
 ObjectPath - путь к объекту WMI,
 Flags - опции,
 WbemNamedValueSet - контекстная информация для провайдера.

Пример использования метода Get:

' Подключение к пространству имен
Set mSWbemServices = GetObject("winmgmts:\.RootCIMv2")
' Получение экземпляра класса с заданным свойством
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:\.RootCIMv2")
' Получение всех экземпляров класса с заданным свойством
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:\.RootCIMv2")
' Получение указателя на класс
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:\.RootCIMv2")
' Создание объекта "слива событий"
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:\.RootCIMv2")
' Получение объекта логического диска
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 & "RootCIMv2")
' Получение колекции файлов целевой папки
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 & "RootCIMv2")
' Получение колекции 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 & "RootCIMv2")
' Получение колекции локальных принтеров
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 & "RootCIMv2")
' Получение коллекции адаптеров с указанным 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}!\.rootcimv2")
           ' Выполнение запроса
           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("\.rootcimv2", 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 & "rootcimv2").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 & "rootcimv2", 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 & "rootcimv2", 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 & "rootcimv2", 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 по этой ссылке.

Administration via WMI - wmiscriptomatic

WMI Scriptomatic — Инициализация

Administration via WMI - wmiscriptomatic

WMI Scriptomatic — Win32_OpepatingSystem

Программа WMI Code Creator представляет из себя генератор кода, который использует WMI для получения информации и для осуществления задач упраления компьютерами. Программа может помочь научиться использовать WMI-скрипты и WMI-приложения для управления как локальным, так и удаленным компьютером. Инструмент доступен на сайте Microsoft по этой ссылке.

Используя WMI Code Creator можно найти любую информацию о компьютере: имя и версия операционной системы, свободное место на диске, состояние сервисов и так далее. Можно выполнить метод из WMI класса для осуществления управления компьютером: создать или удалить сервис, запустить или закрыть программы, назначить разрешения на папку или файл и многое другое. Этот инструмент так же позволяет просматривать доступное WMI-пространство и WMI-классы, чтобы найти нужную для программирования инстанцию с ее описанием, свойствами, методами и примером использования.

Administration via WMI - wmicodecreator

WMI Code Creator — Query

Administration via WMI - wmicodecreator

WMI Code Creator — Method

Administration via WMI - wmicodecreator

WMI Code Creator — Event

Administration via WMI - wmicodecreator

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.

Виталий Бочкарев

Технология WMI (Windows Management Instrumentation) — это одна из базовых технологий Microsoft для централизованного управления и слежения за работой различных частей компьютерной сети под управлением Windows. WMI пригодится прежде всего администраторам Windows, а также разработчикам программного обеспечения. Технология WMI — это реализация модели управления предприятием на базе Web (Web-Based Enterprise Management, WBEM), которая в свою очередь разработана при участии не только компании Microsoft, но и целого ряда других компаний. Задачей WBEM является разработка таких стандартов удалённого управления информационной средой предприятия, которые не зависят от конкретного оборудования, сетевой инфраструктуры, операционной системы, файловой системы и т.д. В рамках WBEM была предложена схема Common Information Model (CIM), которая представляет структуру компьютерной системы в виде единой расширяемой объектно-ориентированной модели и поддерживается в WMI.

Можно автоматизировать работу с WMI с помощью сценариев Windows Script Host (WSH), используя при этом совместно с WMI и другие ActiveX-технологии (например, ActiveX Data Object (ADO) для доступа к базам данных или Active Directory Service Interface (ADSI) для работы со службами каталогов), получив таким образом мощный и удобный инструмент для системного администратора и программиста. Все примеры сценариев WSH в настоящей статье будут приводиться на языке VBScript. Имейте в виду, что сценарии, приведённые в настоящей статье, написаны не для практического применения, а лишь для иллюстрации излагаемого материала (например, в сценариях отсутствует какая-либо обработка ошибок, что совершенно не годится для настоящих рабочих сценариев). Кроме того, вы не найдёте здесь много готовых рецептов для решения конкретных задач администрирования, поскольку цель приведённых примеров — опять же, лишь ознакомление со структурой и возможностями WMI.

Технология WMI реализована для всех 32-разрядных версий Windows, начиная с Windows 95 OSR 2 и заканчивая Windows Server 2003. В операционных системах Windows Me/2000/XP и Windows Server 2003 никакой дополнительной установки WMI не требуется, здесь уже функционирует ядро WMI версии 1.5. Для операционных систем Windows 9x/NT необходимо обновить ядро WMI до версии 1.5. Необходимый для этого инсталяционный файл wmicore.exe можно скачать с сервера Microsoft.

WMI состоит из следующих частей:

  • Менеджер объектов CIM (Common Information Model Object Manager, CIMOM), который обеспечивает обработку всех запросов конечных приложений к WMI и доставку информации от WMI к конечным приложениям. Все провайдеры WMI (см. ниже) должны быть зарегистрированы с помощью CIMOM для правильного перенаправления полученных от конечного приложения запросов к нужному провайдеру. Функциональность CIMOM обеспечивает файл winmgmt.exe, который находится в каталоге %SystemRoot%System32Wbem. Этот файл запускается как сервис.
  • Репозиторий (хранилище классов) CIM. Объекты-экземпляры таких классов создаются провайдером WMI (см. ниже) по запросу потребителя. В Windows Server 2003 и Windows XP репозиторий физически располагается в каталоге %SystemRoot%System32WbemRepositiryFS в файлах objects.data (репозиторий), index.btr (индексный файл), index.map и object.map (файлы контроля над транзакциями). В более ранних версиях Windows репозиторий располагается в файле cim.rep.
  • Провайдеры WMI, которые скрывают детали внутренней реализации управляемых объектов, позволяя CIMOM обращаться к этим объектам единообразно, используя WMI API. Фактически провайдеры являются COM-серверами, которые представлены dll-библиотеками в каталоге %SystemRoot%System32Wbem. WMI включает множество встроенных провайдеров, которые предназначены для получения данных из различных источников, например, журналов событий, системного реестра и т.д.
  • Библиотека поддержки сценариев (WMI scripting library), которая располагается в файле wbemdisp.dll в каталоге %SystemRoot%System32Wbem.

Ваше приложение может обратиться с запросом к любой удалённой машине, на которой установлен WMI. При этом происходит соединение с CIMOM на удалённой машине, после чего запросы обрабатываются точно также, как и на локальной машине. CIMOM проверяет права пользователя, который пытается воспользоваться сервисами WMI на локальном или удалённом компьютере. Потребители WMI (конечные приложения) могут обращаться к управляемым объектам с помощью специального языка запросов WMI Query Language (WQL). CIMOM позволяет создавать обработчики событий управляемых объектов (например, снижение объёма дискового пространства до заданного значения, запуск определённого процесса и т.п.). Для этого CIMOM периодически опрашивает нужный объект (интервал опроса задаётся в конечном приложении) и в случае необходимости генерирует событие.

Количество классов CIM зависит от версии операционной системы. Например, для Windows Server 2003 в CIM хранится около 5000 классов. Классы, составляющие CIM, находятся в иерархической зависимости друг от друга, и классы-потомки могут наследовать, переопределять и добавлять свойства родительских классов. Классы CIM группируются в пространства имён (namespaces), которые упорядочены иерархически. Корневое пространство имён обозначается как Root. В любом варианте установки WMI имеются четыре пространства имён, которые находятся на один уровень ниже корневого пространства имён: CIMV2, Default, Security и WMI.

Общие сведения о классах WMI

Все классы внутри одного пространства должны иметь уникальные имена (при этом имена классов из разных пространств могут совпадать). Класс не может иметь предка или потомка из другого пространства имён.

Полный путь к классу CIM имеет следующую структуру:

\ComputerNameNamespace:ClassName.KeyProperty1=Value1, KeyProperty2=Value2 …

Здесь:

  • ComputerName — сетевое имя компьютера. Для задания локального компьютера можно использовать символ «.».
  • Namespace — название пространства имён.
  • ClassName — имя класса.
  • KeyProperty1=Value1, KeyProperty2=Value2 … — список ключевых пар «свойство-значение» объекта.

Например, экземпляр класса Win32_Process из пространства имён CIMV2 с идентификатором 4, запущенный на локальной машине, определяет такой путь:

\.RootCIMV2:Win32_Process.Handle=4

Всякому ресурсу, управляемому с помощью WMI, соответствует свой класс. Каждый класс имеет свойства, методы и квалификаторы. Также свои квалификаторы могут быть у каждого свойства и метода.

Типы классов по способу хранения информации об управляемых ресурсах:

  • Абстрактный класс (abstract class) — шаблон для образования классов-потомков (абстрактных и неабстрактных), не может использоваться для получения экземпляра управляемого ресурса.
  • Статический класс (static class) — моделирует данные, которые физически хранятся в репозитории CIM (например, данные о собственных настройках WMI). Доступ к экземплярам статических классов осуществляется без помощи каких-либо провайдеров.
  • Динамический класс (dynamic class) — моделирует данные управляемого ресурса через соответствующего провайдера.

Ассоциативный класс (association class) — это класс, который описывает логическую связь между классами или управляющими ресурсами. Может быть абстрактным, статическим или динамическим.

Типы классов по принадлежности к информационным моделям:

  • Системные классы — служат для задания конфигурации и выполнения внутренних функций WMI (обеспечение безопасности, регистрация провайдеров, подписка на события и пр.). Могут быть абстрактными или статическими. Имена всех системных классов начинаются с символов «__» (двойное подчёркивание).
  • Классы модели ядра (core model) — абстрактные классы, которые обеспечивают интерфейс со всеми областями управления (например, абстрактный класс CIM_LogicalElement, который описывает логический управляемый ресурс, например, файл или каталог). Имена таких классов начинаются с префикса «CIM_».
  • Классы общей модели (common model) — классы для специфических задач управления, но не зависящие от версии операционной системы. Имена таких классов тоже начинаются с префикса «CIM_».
  • Классы модели расширения (extension model) — классы для специфических задач управления. Например, классы, соответствующие ресурсам среды Win32, начинающиеся с префикса «Win32_».

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

Свойства классов используются для однозначной идентификации экземпляра класса, представляющего конкретный управляемый ресурс, а также для описания текущего состояния этого ресурса. В основном в WMI свойства классов доступны только для чтения, но значения определённых свойств некоторых классов можно изменять методом Put_(). Возможность изменения конкретного свойства может зависеть от версии операционной системы. Чтобы узнать, является ли свойство доступным для записи, можно проверить значение квалификатора write этого свойства (о квалификаторах см. ниже).

Методы класса позволяют выполнить те или иные действия над управляемым ресурсом, которому соответствует этот класс. Так как не над каждым ресурсом можно производить какие-либо операции, то не у всякого класса есть методы.

Квалификаторы содержат дополнительную информацию о классе, свойстве или методе, в котором они определены.

Квалификаторы классов предоставляют информацию о классе в целом, например, тип класса (квалификаторы Abstract, Dynamic, Association, которые могут принимать булевы значения), имя провайдера класса (квалификатор Provider), информацию о том, поддерживает ли класс создание, уничтожение, изменение экземпляров (квалификаторы SupportsCreate, SupportsDelete, SupportsUpdate которые могут принимать булевы значения), UUID класса (квалификатор UUID), названия методов создания, уничтожения экземпляров (квалификаторы CreateBy, DeleteBy) и т.п.

Квалификаторы свойств позволяют определить тип данного свойства (квалификатор CIMType), доступность для чтения (квалификатор Read), доступность для записи (квалификатор Write), набор допустимых значений для свойства (квалификатор ValueMap) и т.п.

Квалификаторы методов могут описывать множество значений, которые будут возвращаться методом (квалификатор ValueMap), права, которые необходимы для вызова метода (квалификатор Privileges) и т.п. Выполнять можно только те методы, у которых есть квалификатор Implemented со значением True.

Общие сведения о событиях в WMI

Одной из наиболее мощных возможностей WMI является так называемая подписка на извещения о событиях WMI, т.е. создание собственных обработчиков определённых событий WMI. Примерами событий могут послужить снижение объёма дискового пространства на сервере до заданного значения, появление в журнале событий определённого сообщения, запуск или завершение работы определённого приложения и т.д.

События в WMI разделяются на внутренние, внешние и события таймера. Внешние события представлены классом __ExtrinsicEvent, события таймера — классом __TimerEvent, а внутренние события — классами __NamespaceOperationEvent, __ClassOperationEvent и __InstanceOperationEvent. При наступлении события WMI автоматически создаёт экземпляр того класса, которому соответствует это событие.

Внутренние события позволяют контролировать изменения в состоянии тех управляемых ресурсов, которые представлены отдельным классом WMI, а также изменения в структуре самого репозитория CIM. Событиям, которые связаны с управляемыми ресурсами, соответствуют классы, которые порождены от класса __InstanceOperationEvent. Это классы __InstanceCreationEvent, __InstanceModificationEvent и __InstanceDeleionEvent, отвечающие за создание, модификацию и удаление экземпляра класса.

Для подписки на извещения о внутренних событиях применяются запросы специального вида на языке WQL.

Если возникает необходимость контроля состояния какого-либо объекта, для которого в CIM не предусмотрено отдельного класса, используются внешние события. Пример внешнего события — изменение значения определённого ключа в реестре. Для создания внешнего события необходимо, чтобы данное событие поддерживалось соответствующим провайдером WMI.

Для подписки на извещения о внешнем событии из сценария WSH нужно с помощью метода ExecNotificationQueryAsync класса SWbemServices выполнить асинхронный WQL-запрос специального вида.

События таймера могут происходить один раз в определённое время или несколько раз через заданные интервалы времени, что настраивается самим потребителем событий.

Потребители событий могут быть временными и постоянными.

Временные потребители событий — это приложения, которые получают извещения о событиях только во время своей активности. Такими потребителями могут быть сценарии WSH.

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

Безопасность при работе с WMI

По умолчанию с помощью утилит и сценариев WMI пользователь может на определённой машине выполнить только те действия, на которые ему даны разрешения на этой машине. Таким образом реализуется безопасность WMI на уровне операционной системы. Дополнительно политика безопасности в WMI реализована на уровнях пространств имён и протокола DCOM (Distributed COM).

Каждый объект операционной системы, доступ к которому определяет система безопасности (файл, процесс, служба и т.д.), имеет дескриптор безопасности (Security Descriptor, SD), в котором хранится таблица контроля доступа (Access Control List, ACL) для этого объекта. Каждое пространство имён может иметь собственный дескриптор безопасности, в котором хранится таблица контроля доступа. Каждая запись в таблице контроля доступа содержит информацию о том, какие права имеет определённый пользователь при выполнении определённых операций в этом пространстве имён. Список разрешений:

Разрешение Описание
Выполнение методов (Execute Methods) Позволяет вызывать методы классов этого пространства имён. Если пользователь имеет это разрешение, но не имеет разрешения на выполнение операции, которую производит метод, в операционной системе, произойдёт отказ при выполнении метода.
Полная запись (Full Write) Позволяет создавать и модифицировать подпространства имён, системные классы и экземпляры классов.
Частичная запись (Partial Write) Позволяет создавать и модифицировать любые статические классы и экземпляры несистемных классов.
Запись поставщика (Provider Write) Позволяет записывать в репозиторий CIM классы провайдеров WMI и экземпляры этих классов.
Включить учётную запись (Enable Account) Право чтения данных WMI.
Включить удалённо (Remote Enable) Право доступа к WMI на удалённом компьютере. По умолчанию это разрешение есть только у администраторов.
Прочесть безопасность (Read Security) Позволяет читать дескриптор безопасности этого пространства имён.
Изменение правил безопасности (Edit Security) Позволяет изменять дескриптор безопасности этого пространства имён.

Все записи таблицы контроля доступа сохраняются в репозитории WMI. Разрешения WMI для конкретного пространства имён наследуются для всех подпространств имён и классов этого пространства имён. Собственных разрешений безопасности для отдельных классов не существует.

В Windows NT/2000/XP по умолчанию группа администраторов обладает всеми разрешениями. Остальные пользователи обладают разрешениями Включить учётную запись (Enable Account), Выполнение методов (Execute Methods) и Запись поставщика (Provider Write).

Изменить вышеописанные разрешения уровня пространств имён можно запустив элемент управления WMI. Для этого нужно выполнить команду wmimgmt.msc либо в командной строке, либо в меню «Пуск» — «Выполнить». В Windows 9x/Me для открытия элемента управления WMI нужно запустить программу wbemcntl.exe. Если необходимо подключиться к WMI на удалённом компьютере, в открывшейся консоли нужно выбрать меню «Действие» — «Подключение к другому компьютеру…». Для входа в режим просмотра и изменения параметров WMI нужно выбрать меню «Действие» — «Свойства». Примечание: к WMI на локальном компьютере можно получить доступ только от имени текущего пользователя. Чтобы задать разрешения WMI, в окне свойств следует выбрать вкладку «Безопасность», выбрать нужное пространство имён и нажать кнопку «Безопасность». В том же окне свойств можно задать пространство имён WMI, используемое по умолчанию для написания сценариев (вкладка «Дополнительно»).

Для доступа к WMI на удалённом компьютере используется протокол DCOM (Distributed COM). Пользователь, который запускает сценарий или подключается к WMI с помощью специальных утилит, выступает в качестве клиента, а объект WMI, к которому идёт обращение, является сервером. Для того, чтобы определить, какие права будут применяться при работе с WMI на удалённом компьютере, используются уровни олицетворения протокола DCOM:

Уровень Описание
Анонимный доступ (Anonymous, 1) Объект-сервер не может получить информацию о клиенте (не может олицетворить клиента). Этот уровень олицетворения в WMI не используется.
Идентификация (Identify, 2) Объект-сервер может получить информацию о клиенте, но не может олицетворить клиента. Этот уровень олицетворения не позволяет запускать сценарии WMI на удалённых машинах.
Олицетворение (Impersonate, 3) Объект-сервер может пользоваться всеми правами клиента.
Делегирование (Delegate, 4) Объект-сервер может обратиться от имени клиента к другому объекту-серверу.

Уровень олицетворения протокола DCOM, выбираемый по умолчанию при обращении к серверу DCOM, зависит от версии WMI на целевом компьютере. Чтобы изменить уровень по умолчанию, необходимо записать его наименование в следующий ключ реестра:

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWBEMScriptingDefault Impersonation Level

В сценариях WSH нужный уровень олицетворения можно указать в явном виде в момент соединения с WMI.

Протокол DCOM позволяет также установить определённый уровень аутентификации (проверки подлинности). Возможные уровни:

Уровень Описание
Отсутствует (None, 1) Проверка подлинности отсутствует.
По умолчанию (Default, 0) Используются стандартные настройки безопасности, заданные на сервере.
Подключений (Connect, 2) Клиент проходит проверку подлинности только во время подключения к серверу. После того, как соединение установлено, никаких проверок не производится.
Вызовов (Call, 3) Клиент проходит проверку подлинности в начале каждого вызова во время приёма запросов сервером. Заголовки пакетов подписываются, но содержимое пакетов не подписывается и не шифруется.
Пакетов (Pkt, 4) То же, что и предыдущее, но проверке подлинности подвергаются все пакеты, поступающие от клиента.
Целостности пакетов (PktIntegrity, 5) Все пакеты проходят проверку подлинности и целостности (т.е. проверяется, что содержимое пакета не было изменено во время передачи). Данные подписываются, но не шифруются.
Секретности пакетов (PktPrivacy, 6) То же, что и предыдущее, но данные шифруются.

В сценариях WSH нужный уровень аутентификации можно указать в явном виде в момент соединения с WMI. При локальной работе с WMI DCOM всегда использует уровень секретности пакетов (PktPrivacy).

Подключение к WMI в сценариях WSH с помощью объекта SWbemLocator

Для подключения к WMI с помощью сценариев WSH существуют два варианта: с использованием объекта SWbemLocator и с помощью WMI-моникера (WMI moniker) «WinMgmts:».

Объект SWbemLocator позволяет установить соединение с определённым пространством имён WMI на удалённом компьютере от имени заданной учётной записи или на локальном компьютере от имени текущей учётной записи. Использование этого объекта необходимо, если в сценарии нужно явно задать имя пользователя и пароль для подключения к пространству имён WMI. Объект SWbemLocator создаётся следующим образом:

Set objSWbemLocator = CreateObject(«WbemScripting.SWbemLocator»)

Единственный метод ConnectServer объекта SWbemLocator позволяет подключиться к WMI и получить ссылку на объект SWbemServices. Синтаксис вызова метода:

objSWbemServices = objSWbemLocator.ConnectServer([strServer], [strNamespace], [strUser], [strPassword], [strLocale], [strAuthority], [iSecurityFlags], [objWbemNamedValueSet])

Параметры метода:

  • strServer — имя компьютера. Если не указано, подключение будет производиться к локальному компьютеру.
  • strNamespace — пространство имён. Если не указано, будет использовано пространство имён, заданное по умолчанию.
  • strUser — имя пользователя в формате DomainUsername. Если не указано, будет использована текущая учётная запись. Если параметр указан для локального соединения, произойдёт ошибка (к локальному компьютеру можно подключаться только от имени текущей учётной записи).
  • strPassword — пароль пользователя.
  • strLocale — код локализации. Если не указан, будет использован текущий регион (язык). Формат строки — «MS_xxxx», где xxxx — строка в шестнадцатеричной форме, которая указывает LCID. Например, американский английский указывается как «MS_409».
  • strAuthority — имя домена. Если домен уже определен в параметре strUser, повторное указание домена в этом параметре приведёт к ошибке. Если этот параметр начинается со строки «kerberos:», будет использована идентификация Kerberos.
  • iSecurityFlags — влияет на время ожидания подключения. Если параметр установлен в 0, управление будет передано на следующую строку программы (скрипта) только после того, как подключение к серверу будет установлено. Если параметр установлен в 128, максимальное время ожидания подключения — 2 минуты.
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Единственное свойство Security_ объекта SWbemLocator содержит объект SWbemSecurity, который служит для чтения и установки параметров безопасности (привилегий, уровня олицетворения и уровня аутентификации). Свойства объекта SWbemSecurity:

Свойство Описание
AuthenticationLevel Целое число, которое определяет уровень аутентификации. Возможные значения — см. выше описание уровней аутентификации DCOM.
ImpersonationLevel Целое число, которое определяет уровень олицетворения. Возможные значения — см. выше описание уровней олицетворения DCOM.
Privileges Объект SWbemPrivilegeSet, определяющий различные разрешения.

Свойства и методы объекта SWbemPrivilegeSet:

Свойство / метод Описание
Count Содержит число элементов в коллекции. Только чтение.
Add(iPrivilege, [bIsEnabled = True]) Добавляет в коллекцию объект SWbemPrivilege и возвращает его. Если объект с таким именем уже существует в коллекции, он перезаписывается. Параметр iPrivilege задаёт целое число, определяющее разрешение. Параметр bIsEnabled — булево значение, включающее или запрещающее это разрешение. Возможные значения параметра iPrivilege:

  • 1 (wbemPrivilegeCreateToken, SeCreateTokenPrivilege) — возможность создавать первичный маркер.
  • 2 (wbemPrivilegePrimaryToken, SeAssignPrimaryTokenPrivilege) — возможность назначать первичный маркер процесса.
  • 3 (wbemPrivilegeLockMemory, SeLockMemoryPrivilege) — возможность блокировать физические страницы в памяти.
  • 4 (wbemPrivilegeIncreaseQuota, SeIncreaseQuotaPrivilege) — возможность увеличивать квоту, назначенную на процесс.
  • 5 (wbemPrivilegeMachineAccount, SeMachineAccountPrivilege) — возможность создавать учетную запись машины.
  • 6 (wbemPrivilegeTcb, SeTcbPrivilege) — идентифицирует держателя как часть доверенной компьютерной базы (trusted computer base).
  • 7 (wbemPrivilegeSecurity, SeSecurityPrivilege) — исполняет множество связанных с безопасностью функций, типа управления и рассмотрения сообщений аудита. Эта привилегия идентифицирует ее держателя как оператора безопасности (security operator).
  • 8 (wbemPrivilegeTakeOwnership, SeTakeOwnershipPrivilege) — возможность монопольного использования объекта без предоставления контролируемого доступа.
  • 9 (wbemPrivilegeLoadDriver, SeLoadDriverPrivilege) — возможность загрузки и выгрузки драйвера устройства.
  • 10 (wbemPrivilegeSystemProfile, SeSystemProfilePrivilege) — возможность сбора информации профилирования (profiling information) для всей системы.
  • 11 (wbemPrivilegeSystemtime, SeSystemtimePrivilege) — возможность изменять системное время.
  • 12 (wbemPrivilegeProfileSingleProcess, SeProfileSingleProcessPrivilege) — возможность сбора информации профилирования (profiling information) для отдельного процесса.
  • 13 (wbemPrivilegeIncreaseBasePriority, SeIncreaseBasePriorityPrivilege) — возможность увеличивать базовый приоритет процесса.
  • 14 (wbemPrivilegeCreatePagefile, SeCreatePagefilePrivilege) — возможность создавать файл подкачки.
  • 15 (wbemPrivilegeCreatePermanent, SeCreatePermanentPrivilege) — возможность создавать постоянный объект.
  • 16 (wbemPrivilegeBackup, SeBackupPrivilege) — возможность исполнять операции резервного копирования.
  • 17 (wbemPrivilegeRestore, SeRestorePrivilege) — возможность исполнять операции восстановления, возможность установить любого допустимого пользователя или идентификатор безопасности группы (SID) как владельца объекта.
  • 18 (wbemPrivilegeShutdown, SeShutdownPrivilege) — возможность завершать работу локальной системы.
  • 19 (wbemPrivilegeDebug, SeDebugPrivilege) — возможность отладки процесса.
  • 20 (wbemPrivilegeAudit, SeAuditPrivilege) — возможность генерировать элементы лога аудита.
  • 21 (wbemPrivilegeSystemEnvironment, SeSystemEnvironmentPrivilege) — возможность изменять энергонезависимую RAM память систем, чтобы использовать этот тип памяти для хранения информации конфигурации.
  • 22 (wbemPrivilegeChangeNotify, SeChangeNotifyPrivilege) — возможность получать уведомления об изменениях файлов и каталогов. Это допускается по умолчанию для всех пользователей.
  • 23 (wbemPrivilegeRemoteShutdown, SeRemoteShutdownPrivilege) — возможность удалённо завершать работу системы.
  • 24 (wbemPrivilegeUndock, SeUndockPrivilege) — возможность удалять портативный компьютер из док-станции.
  • 25 (wbemPrivilegeSyncAgent, SeSyncAgentPrivilege) — возможность синхронизировать данные службы каталога.
  • 26 (wbemPrivilegeEnableDelegation, SeEnableDelegationPrivilege) — возможность разрешать учётные записи компьютера и пользователя для доверенного делегирования.
AddAsString(strPrivilege, [bIsEnabled = True]) Добавляет в коллекцию объект SWbemPrivilege и возвращает его. Параметр strPrivilege задаёт строку, определяющую разрешение. Например, для использования разрешения завершать работу локальной системы нужно использовать строку SeShutdownPrivilege. Возможные значения строк — см. выше описание метода Add(). Параметр bIsEnabled — булево значение, включающее или запрещающее это разрешение.
Item(iPrivilege) Возвращает объект SWbemPrivilege. Параметр iPrivilege задаёт целое число, определяющее разрешение. Возможные значения — см. выше описание метода Add().
DeleteAll() Очищает коллекцию.
Remove(iPrivilege) Удаляет разрешение из коллекции. Параметр iPrivilege задаёт целое число, определяющее разрешение. Возможные значения — см. выше описание метода Add().

Свойства объекта SWbemPrivilege:

Свойство Описание
DisplayName Содержит краткое описание разрешения. Только чтение.
Identifier Содержит идентификатор разрешения (целое число). Только чтение. Возможные значения — см. выше описание метода Add() объекта SWbemPrivilegeSet.
IsEnabled Содержит булево значение, определяющее, включено или запрещено это разрешение.
Name Содержит имя разрешения. Только чтение. Возможные значения — см. выше описание метода Add() объекта SWbemPrivilegeSet. Например, имя разрешения завершать работу локальной системы будет строкой «SeShutdownPrivilege».

Пример подключения:

Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
'Уровень аутентификации - уровень секретности пакетов:
objSWbemLocator.Security_.AuthenticationLevel = 6
'Уровень олицетворения - олицетворение:
objSWbemLocator.Security_.ImpersonationLevel = 3
'Добавление разрешения завершать работу локальной системы:
objSWbemLocator.Security_.Privileges.AddAsString("SeShutdownPrivilege")
'Вывод краткого описания добавленного разрешения:
WScript.Echo "Добавлено разрешение:"
WScript.Echo objSWbemLocator.Security_.Privileges.Item(18).DisplayName
'Подключение:
Set objSWbemServices = objSWbemLocator.ConnectServer(".", "RootCIMV2",,,,, 128)

Подключение к WMI в сценариях WSH с помощью WMI-моникера «WinMgmts:»

Для подключения к WMI с помощью сценариев WSH существуют два варианта: с использованием объекта SWbemLocator и с помощью WMI-моникера (WMI moniker) «WinMgmts:».

Моникер — это строка определённой структуры, задающая путь к объекту, экземпляр которого должен быть создан. Моникер передаётся в качестве параметра функции GetObject(). Моникер состоит из следующих частей:

  • Обязательный префикс «winmgmts:».
  • Необязательные параметры настройки безопасности WMI.
  • Необязательный путь к нужному объекту WMI.

Регистр символов префикса «winmgmts:» неважен. Самый простой моникер состоит только из этого префикса. Такой моникер подключается к пространству имён по умолчанию (как правило, это RootCIMV2) на локальном компьютере:

Set objService = GetObject(«winmgmts:»)

Связь WMI-моникера «winmgmts:» с библиотекой поддержки сценариев WMI осуществляется с помощью такого раздела реестра:

HKEY_CLASSES_ROOTWINMGMTSCLSID

В значении по умолчанию вышеуказанного раздела записан идентификатор, указывающий на другой раздел реестра:

HKEY_CLASSES_ROOTCLSID<Идентификатор>InProcServer32

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

После префикса «winmgmts:» можно указать в фигурных скобках следующие параметры безопасности:

  • Уровень олицетворения DCOM, например «winmgmts:{impersonationLevel=Impersonate}».
  • Уровень аутентификации DCOM, например «winmgmts:{authenticationLevel=pktPrivacy}».
  • Источник проверки подлинности (домен), например «winmgmts:{authority=NTLMDomain:Domain1}» или «winmgmts:{authority=Kerberos:Domain1Server1}». Возможно использование протокола Kerberos или NT LAN Manager (NTLM). При установке связи с WMI на локальном компьютере параметр authority не указывается.
  • Назначенные и отозванные привилегии в дополнительных круглых скобках, например «winmgmts:{(Shutdown, !RemoteShutdown)}». Возможные значения привилегий — см. выше описание метода Add() объекта SWbemPrivilegeSet. При указании привилегий префикс «Se» и суффикс «Privilege» отбрасываются, т.е. например, «SeShutdownPrivilege» указывается как «Shutdown». Отозванные привилегии предваряются восклицательным знаком.

Пример совместного указания параметров безопасности:

«winmgmts:{impersonationLevel=Impersonate, authenticationLevel=pktPrivacy, authority=NTLMDomain:Domain1, (Shutdown, RemoteShutdown)}»

Способы задания пути к нужному объекту WMI описаны выше в разделе «Общие сведения о классах WMI». Если параметры безопасности указаны, путь к объекту предваряется восклицательным знаком, например:

«winmgmts:{impersonationLevel=Impersonate, (Shutdown, RemoteShutdown)}!\.RootCIMV2:Win32Process.Handle=4»

Если параметры безопасности не указаны, путь к объекту записывается без восклицательного знака, например:

«winmgmts:\.RootCIMV2:Win32Process.Handle=4»

Пример подключения:

Set objSWbemServices = GetObject(«winmgmts:{impersonationLevel=Impersonate}!\.RootCIMV2»)

Работа с объектом SWbemServices

В результате подключения к WMI (как с помощью объекта SWbemLocator, так и с помощью моникера) можно получить объект SWbemServices, который обладает рядом свойств и методов. Объект SWbemServices возвращается в случае, если подключение производится к пространству имён.

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

Некоторые свойства и методы объекта SWbemServices (полное описание свойств и методов — см. MSDN):

Свойство / метод Описание
Security_ Содержит объект SWbemSecurity, который служит для чтения и установки параметров безопасности (привилегий, уровня олицетворения и уровня аутентификации). Описание этого объекта было приведено выше в разделе «Подключение к WMI в сценариях WSH с помощью объекта SWbemLocator».
InstancesOf(strClass, [iFlags = 16], [objWbemNamedValueSet = null]) Возвращает коллекцию SWbemObjectSet объектов указанного класса согласно критериям выбора. Этот метод осуществляет простой запрос. Более сложные запросы могут потребовать использования метода ExecQuery(). Метод InstancesOf() работает в синхронном и полусинхронном режиме. Параметры:

  • strClass — имя класса.
  • iFlags — опции, комбинация флагов. Некоторые возможные значения (подробнее — см. MSDN):
    • wbemFlagReturnImmediately (16) — значение по умолчанию для этого параметра. Приводит к немедленному возврату результатов запроса (полусинхронный режим).
    • wbemFlagForwardOnly (32) — возвращает коллекцию типа forward-only (навигация только вперёд). Максимальная производительность и экономия памяти.
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Пример использования метода — см. ниже текст скрипта, который выводит перечень всех доступных пространств имён WMI на указанном компьютере.

Get([strObjectPath = «» ], [iFlags = 0], [objWbemNamedValueSet = null]) Возвращает определение класса или экземпляр управляемого ресурса (объект SWbemObject). Метод работает в синхронном режиме. Параметры:

  • strObjectPath — путь к объекту в WMI. Если параметр не задан, возвращается пустой объект.
  • iFlags — опции, комбинация флагов. Возможные значения — см. MSDN.
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Пример использования метода:
‘подключение к пространству имён
Set objService = GetObject(«winmgmts:\.RootCIMV2»)
‘получение экземпляра класса с заданным ключевым свойством
Set objProcess = objService.Get(«Win32_Process.Handle=4»)

ExecQuery(strQuery, [strQueryLanguage = «WQL»], [iFlags = 16], [objWbemNamedValueSet = null]) Выполняет запрос на языке WQL (WMI SQL) и возвращает коллекцию SWbemObjectSet. Синтаксис языка WQL напоминает SQL и полностью описан в MSDN. Метод работает в синхронном и полусинхронном режиме. Параметры:

  • strQuery — текст запроса.
  • strQueryLanguage — используемый язык запросов. Если параметр задан, его значение должно быть всегда «WQL».
  • iFlags — опции, комбинация флагов. Некоторые возможные значения (подробнее — см. MSDN):
    • wbemFlagReturnImmediately (16) — значение по умолчанию для этого параметра. Приводит к немедленному возврату результатов запроса (полусинхронный режим).
    • wbemFlagForwardOnly (32) — возвращает коллекцию типа forward-only (навигация только вперёд). Максимальная производительность и экономия памяти.
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Пример использования метода:
‘подключение к пространству имён
Set objService = GetObject(«winmgmts:\.RootCIMV2»)
‘получение всех экземпляров класса с заданным свойством
Set colProcesses = objService.ExecQuery(«Select * from Win32_Process Where Handle = 4»)

SubclassesOf([strSuperclass = «»], [iFlags = 16], [objWbemNamedValueSet = null]) Возвращает коллекцию SWbemObjectSet, содержащую совокупность подклассов указанного класса. Метод работает в синхронном и полусинхронном режиме. Параметры:

  • strSuperclass — Имя класса, подклассы которого требуется получить. Если параметр не указан, будут возвращены все классы верхнего уровня, т.е. классы не имеющие родительского класса (если параметр iFlags содержит флаг wbemQueryFlagShallow), или вообще все классы в пределах текущего пространства имён.
  • iFlags — опции, комбинация флагов. Некоторые возможные значения (подробнее — см. MSDN):
    • wbemQueryFlagShallow (1) — включать только непосредственные подклассы указанного класса.
    • wbemFlagReturnImmediately (16) — значение по умолчанию для этого параметра. Приводит к немедленному возврату результатов запроса (полусинхронный режим).
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

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

Delete(strObjectPath, [iFlags = 0], [objWbemNamedValueSet = null]) Удаляет экземпляр управляемого ресурса. Не у всякого класса можно удалять экземпляры. Признаком того, что класс поддерживает удаление своих экземпляров, является, как правило, наличие у класса квалификатора SupportsDelete со значением True. Метод Delete() работает в синхронном режиме. Параметры:

  • strObjectPath — путь к объекту.
  • iFlags — зарезервировано. Параметр должен содержать ноль.
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Пример использования метода:
Set objService = GetObject(«winmgmts:\.RootCIMV2»)
objService.Delete(«__EventFilter.Name=’MonitoringServices’»)

ExecMethod(strObjectPath, strMethodName, [objWbemInParams = null], [iFlags = 0], [objWbemNamedValueSet = null]) Исполняет указанный метод указанного объекта. Работает в синхронном режиме. Параметры:

  • strObjectPath — путь к объекту.
  • strMethodName — имя метода.
  • objWbemInParams — объект SWbemObject, который содержит входные параметры для выполняемого метода.
  • iFlags — зарезервировано. Параметр должен содержать ноль.
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Пример использования метода:
‘подключение к пространству имён
Set objService = GetObject(«winmgmts:\.RootCIMV2»)
‘получение указателя на класс
Set objProcess = objService.Get(«Win32_Process»)
‘создание коллекции входных параметров метода
Set objInParams = objProcess.Methods_(«Create»).InParameters.SpawnInstance_
‘указание входного параметра — командной строки
objInParams.CommandLine = «calc.exe»
‘выполнение метода (запуск процесса)
Set objOutParams = objService.ExecMethod(«Win32_Process», «Create», objInParams)
‘получение идентификатора запущенного процесса
WScript.Echo objOutParams.ProcessId

Описанные выше методы объекта SWbemServices работают в синхронном и полусинхронном режимах. Существуют аналогичные методы, работающие в асинхронном режиме. Названия этих методов включают суффикс «Async»: InstancesOfAsync(), GetAsync(), ExecQueryAsync(), SubclassesOfAsync(), DeleteAsync(), ExecMethodAsync(). Асинхронные методы в основном похожи на вышеописанные, но включают дополнительные первый и последний параметры: в первом параметре передаётся ссылка на специальный объект SWbemSink, события которого потом обрабатываются в сценарии, а в последнем параметре — ссылка на специальный объект SWbemNamedValueSet, который используется, если делаются множественные асинхронные запросы с одним и тем же объектом SWbemSink (последний параметр необязателен и здесь не рассматривается, а его исчерпывающее описание можно найти в MSDN). Кроме того, параметр iFlags в асинхронных методах имеет несколько иной набор допустимых значений (подробнее — см. MSDN).

Объект SWbemSink создаётся следующим образом:

Set objSink = WScript.CreateObject(«WbemScripting.SWbemSink», «Sink_»)

Функция CreateObject() объекта WScript позволит в дальнейшем обрабатывать события объекта, а строка «Sink_» является префиксом для функций — обработчиков событий, которые будут описаны в сценарии.

Полное описание событий и методов объекта SWbemSink можно найти в MSDN, здесь же будут рассмотрены два основных события, обработка которых необходима для асинхронных вызовов: это события OnObjectReady() и OnCompleted(). Событие OnObjectReady() происходит, когда возвращается очередной объект, порождённый тем или иным запросом и получает этот объект в качестве одного из своих параметров. Событие OnCompleted() происходит после полного завершения асинхронной операции и получает, помимо прочего, код возврата асинхронной операции (в случае успеха — 0).

В качестве примера приведём скрипт, который получает асинхронно все процессы, запущенные на компьютере:

'подключение к пространству имён
Set objService = GetObject("winmgmts:\.RootCIMV2")
'создание объекта SWbemSink
Set objSink = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")
'асинхронный запрос
bdone = False
objService.ExecQueryAsync objSink, "Select * from Win32_Process"
'цикл ожидания, пока выполнится запрос
While Not bdone
    WScript.Sleep 1000
Wend
'обработчик события OnObjectReady
Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext)
    WScript.Echo objWbemObject.Name 'имя процесса
End Sub
'обработчик события OnCompleted
Sub Sink_OnCompleted(iHResult, objWbemErrorObject, objWbemAsyncContext)
    If iHResult=0 Then 'проверка кода возврата запроса
        WScript.Echo "Запрос завершён успешно."
    End If
    bdone = True 'флаг завершения запроса
End Sub

Работа с объектами SWbemObjectSet и SWbemObject

Рассмотренные выше методы объекта SWbemServices возвращают коллекции объектов SWbemObjectSet или «одиночные» объекты SWbemObject. Объекты SWbemObjectSet и SWbemObject в свою очередь обладают набором специфических свойств и методов.

Коллекция SWbemObjectSet содержит объекты SWbemObject, которые можно перебрать в цикле «For Each» (что продемонстрировано во многих примерах скриптов в этой статье), а также имеет следующие свойства и методы:

Свойство / метод Описание
Item(strObjectPath) Возвращает объект SWbemObject из коллекции. Параметр strObjectPath задаёт относительный путь к объекту. Это достаточно ресурсоёмкий метод.
Count Содержит количество элементов коллекции. Только чтение. Использование этого свойства достаточно ресурсоёмко. Если объект SWbemObjectSet был получен с флагом wbemFlagForwardOnly, при обращении к свойству произойдёт ошибка.
Security_ Содержит объект SWbemSecurity, который служит для чтения и установки параметров безопасности (привилегий, уровня олицетворения и уровня аутентификации). Описание этого объекта было приведено выше в разделе «Подключение к WMI в сценариях WSH с помощью объекта SWbemLocator».

Объект SWbemObject поддерживает два типа свойств и методов: универсальные свойства и методы, присущие любому объекту этого типа, а также набор свойств и методов, присущий определённому классу, которому соответствует объект в данный момент. Универсальные методы свойства заканчиваются конечным символом подчеркивания («_»), чтобы дифференцировать их от методов и свойств конкретного класса. Примечание: если вы изменяете свойства объекта SWbemObject, все изменения будут записаны в WMI только после вызова специального метода Put_(). Вот некоторые универсальные свойства и методы объекта SWbemObject (полное описание свойств и методов объекта SWbemObject можно найти в MSDN):

Свойство / метод Описание
Instances_([iFlags = 16], [objWbemNamedValueSet = null]) Возвращает объект SWbemObjectSet, который содержит экземпляры текущего класса. Этот метод осуществляет простой запрос. Более сложные запросы могут потребовать использования метода ExecQuery() объекта SWbemServices. Параметры:

  • iFlags — опции, комбинация флагов. Некоторые возможные значения (подробнее — см. MSDN):
    • wbemFlagReturnImmediately (16) — значение по умолчанию для этого параметра. Приводит к немедленному возврату результатов запроса (полусинхронный режим).
    • wbemFlagForwardOnly (32) — возвращает коллекцию типа forward-only (навигация только вперёд). Максимальная производительность и экономия памяти.
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Пример использования метода:
‘подключение к классу:
Set objSWbemObject = GetObject(«winmgmts:\.RootCIMV2:Win32_Process»)
‘получение коллекции экземпляров класса:
Set colProcesses = objSWbemObject.Instances_(16+32)
‘перебор экземпляров класса:
For Each objProcess In colProcesses
    WScript.Echo objProcess.Name
Next

ExecMethod_(strMethodName, [objwbemInParams = null], [iFlags = 0], [objwbemNamedValueSet = null]) Исполняет указанный метод объекта. Параметры:

  • strMethodName — имя метода.
  • objwbemInParams — объект SWbemObject, который содержит в своей коллекции Properties_ входные параметры для выполняемого метода.
  • iFlags — зарезервировано. Параметр должен содержать ноль.
  • objwbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Пример использования метода:
‘подключение к классу «Win32_Process»:
Set objProcess = GetObject(«winmgmts:\.RootCIMV2:Win32_Process»)
‘получение объекта, содержащего входные параметры метода «Create» класса «Win32_Process»:
Set objInParams = objProcess.Methods_(«Create»).InParameters.SpawnInstance_
‘задание командной строки
objInParams.CommandLine = «Notepad.exe»
‘запуск процесса
Set objOutParams = objProcess.ExecMethod_(«Create», objInParams)
‘проверка результатов запуска
If objOutParams.ReturnValue = 0 Then
    WScript.echo «Метод «»Create()»» исполнен успешно.»
Else
    If IsNull(objOutParams.ReturnValue) Then
        WScript.echo «Не удалось исполнить метод «»Create()»».»
    Else
        WScript.echo «Метод «»Create()»» исполнен с ошибкой 0x» & hex(objOutParams.ReturnValue)
    End If
End If

SpawnInstance_([iFlags = 0]) Cоздаёт новый пустой экземпляр класса. Параметр iFlags зарезервирован и должен содержать ноль. Пример использования — см. выше описание метода ExecMethod_().
Clone_() Возвращает новый объект, который является копией текущего объекта. Это полезно, когда нужно сохранить оригинальную копию объекта для резервных целей, изменяя при этом новую копию. Например, Вы можете использовать метод SpawnInstance_(), чтобы создать стартовый образец, а затем использовать метод Clone_(), чтобы быстро воспроизвести 100 копий образца.
CompareTo_(objWbemObject, [iFlags = 0]) Сравнивает два объекта SWbemObject. Возвращает True, если объекты совпадают, и False, если объекты не совпадают. Параметры:

  • objWbemObject — объект SWbemObject для сравнения.
  • iFlags — опции сравнения, комбинация флагов. Некоторые возможные значения (подробнее — см. MSDN):
    • wbemComparisonFlagIncludeAll(0) — полное сравнение.
    • wbemComparisonFlagIgnoreQualifiers(1) — игнорирует все квалификаторы при сравнении.
    • wbemComparisonFlagIgnoreObjectSource(2) — игнорирует при сравнении источники объектов, т.е. сервер и пространство имён.
    • wbemComparisonFlagIgnoreClass(8) — предполагает, что сравниваемые объекты — образцы того же самого класса, т.е. сравнивается только информация, связанная с экземпляром. Используйте этот флажок, чтобы оптимизировать выполнение.
    • wbemComparisonFlagIgnoreCase(16) — сравнивает строки без учета регистра. Это применяется и к значениям квалификаторов. Имена квалификаторов всегда сравниваются без учета регистра, определен ли этот флажок или нет.
Delete_([iFlags = 0], [objwbemNamedValueSet = null]) Удаляет текущий класс или экземпляр класса, если такое действие с этим классом поддерживается провайдером. Признаком того, что провайдер динамического класса поддерживает процедуру удаления своих экземпляров, является, как правило, наличие у класса квалификатора SupportsDelete со значением True. Параметры:

  • iFlags — зарезервировано. Параметр должен содержать ноль.
  • objwbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.
Put_([iFlags = 0], [objwbemNamedValueSet = null]) Создаёт или обновляет класс или экземпляр класса после того, как вы изменяете его любые свойства и возвращает объект SWbemObjectPath. Примечание: чтобы узнать, является ли свойство изменяемым, нужно проверить квалификатор Write этого свойства — если данный квалификатор имеется и его значение равно True, свойство доступно для записи. Параметры:

  • iFlags — опции, комбинация флагов. Некоторые возможные значения (подробнее — см. MSDN):
    • wbemChangeFlagUpdateOnly(1) — только обновление. Для успешного исполнения класс или образец должны существовать.
    • wbemChangeFlagCreateOnly(2) — только создание. Для успешного исполнения класс или образец ещё не должны существовать.
    • wbemFlagReturnImmediately(16) — немедленный возврат результата (полусинхронный режим).
  • objwbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Пример использования метода:
‘подключение к пространству имён
Set objService = GetObject(«winmgmts:\.RootCIMV2»)
‘получение объекта логического диска «D:»
Set colDisks = objService.ExecQuery(«Select * from Win32_LogicalDisk Where DeviceID = ‘D:’»)
For Each objDisk In colDisks
    WScript.Echo objDisk.VolumeName
    ‘смена метки тома
    objDisk.VolumeName = «New»
    ‘запись изменений
    objDisk.Put_
    WScript.Echo objDisk.VolumeName
Next

Methods_ Содержит коллекцию методов класса (объект SWbemMethodSet). Только чтение. Пример использования — см. ниже скрипт, который выводит перечень всех доступных свойств, методов и квалификаторов выбранного класса WMI.
Properties_ Содержит коллекцию свойств класса (объект SWbemPropertySet). Только чтение. Пример использования — см. ниже скрипт, который выводит перечень всех доступных свойств, методов и квалификаторов выбранного класса WMI.
Qualifiers_ Содержит коллекцию квалификаторов класса (объект SWbemQualifierSet). Только чтение. Пример использования — см. ниже скрипт, который выводит перечень всех доступных свойств, методов и квалификаторов выбранного класса WMI.
Security_ Содержит объект SWbemSecurity, который служит для чтения и установки параметров безопасности (привилегий, уровня олицетворения и уровня аутентификации). Описание этого объекта было приведено выше в разделе «Подключение к WMI в сценариях WSH с помощью объекта SWbemLocator».
Path_ Содержит объект SWbemObjectPath, предоставляющий набор свойств и методов для получения различной информации об объекте. Пример использования:
‘подключение к пространству имён
Set objService = GetObject(«winmgmts:\.RootCIMV2»)
‘получение объекта логического диска «D:»
Set colDisks = objService.ExecQuery(«Select * from Win32_LogicalDisk Where DeviceID = ‘D:’»)
For Each objDisk In colDisks
    WScript.Echo objDisk.Path_.Class
    WScript.Echo objDisk.Path_.Namespace
    WScript.Echo objDisk.Path_.Path
    WScript.Echo objDisk.Path_.Server
Next

Также существуют методы, аналогичные вышеописанным, но работающие в асинхронном режиме. Названия этих методов включают суффикс «Async»: DeleteAsync(), ExecMethodAsync_(), InstancesAsync_(), PutAsync_() и подобные. Асинхронные методы в основном похожи на вышеописанные, но включают дополнительные первый и последний параметры: в первом параметре передаётся ссылка на специальный объект SWbemSink, события которого потом обрабатываются в сценарии, а в последнем параметре — ссылка на специальный объект SWbemNamedValueSet, который используется, если делаются множественные асинхронные запросы с одним и тем же объектом SWbemSink (последний параметр необязателен и здесь не рассматривается, а его исчерпывающее описание можно найти в MSDN). Кроме того, параметр iFlags в асинхронных методах имеет несколько иной набор допустимых значений (подробнее — см. MSDN). Работа с объектом SWbemSink и способы вызова асинхронных методов описаны выше в разделе «Работа с объектом SWbemServices».

Исследование доступных пространств имён и классов с помощью сценариев WSH

Следующий сценарий выводит перечень всех доступных пространств имён WMI на указанном компьютере:

'Рекурсивная функция вывода всех подпространств имён
'в указанном пространстве имён. Параметры:
'strR  - результат (текст для вывода).
'strNS - выбранное пространство имён.
'strC  - имя компьютера.
Sub Namespace(strR, strNS, strC)
    'Формирование строки результата
    strR = strR & "    " & strNS & vbCrLf
    'Подключение к выбранному пространству имён WMI
    Set objService = GetObject("winmgmts:\" & strC & "" & strNS)
    'Получение коллекции подпространств имён выбранного пространства имён
    Set colNamespaces = objService.InstancesOf("__NAMESPACE")
    'Перебор коллекции
    For Each objNamespace In colNamespaces
        'Рекурсивный вызов
        Call Namespace(strR, strNS & "" & objNamespace.Name, strC)
    Next
End Sub
'==========================================================
strComputer = "."   'имя компьютера
strRes = ""         'результат (текст для вывода)
strBeginNS = "Root" 'имя начального пространства имён
'==========================================================
Call Namespace(strRes, strBeginNS, strComputer)
WScript.Echo strRes

Следующий сценарий выводит перечень всех доступных классов выбранного пространства имён WMI:

strComputer = "."      'имя компьютера
strNS = "RootDefault" 'имя пространства имён
'==========================================================
'Подключение к выбранному пространству имён WMI
Set objService = GetObject("winmgmts:\" & strComputer & "" & strNS)
'Получение коллекции классов выбранного пространства имён
Set colClasses = objService.SubclassesOf()
'Перебор коллекции классов
For Each objClass In colClasses
    WScript.Echo objClass.Path_.Class
Next

Следующий сценарий выводит перечень всех доступных свойств, методов и квалификаторов выбранного класса WMI:

strComputer = "."             'имя компьютера
strNS       = "RootCIMV2"    'имя пространства имён
strClass    = "Win32_Process" 'имя класса
'==========================================================
'Подключение к выбранному классу WMI
Set objClass = GetObject("winmgmts:\" & strComputer & "" & strNS & ":" & strClass)
'Перебор свойств класса
WScript.Echo "Свойства класса " & strNS & ":" & strClass
For Each objProperty In objClass.Properties_
    WScript.Echo objProperty.Name
Next
'Пустая строка (разделитель)
WScript.Echo
'Перебор методов класса
WScript.Echo "Методы класса " & strNS & ":" & strClass
For Each objMethod In objClass.Methods_
    WScript.Echo objMethod.Name
Next
'Пустая строка (разделитель)
WScript.Echo
'Перебор квалификаторов класса
WScript.Echo "Квалификаторы класса " & strNS & ":" & strClass
For Each objQualifier In objClass.Qualifiers_
    If IsArray(objQualifier.Value) Then
        WScript.Echo objQualifier.Name & " = " & Join(objQualifier.Value)
    Else
        WScript.Echo objQualifier.Name & " = " & objQualifier.Value
    End If
Next

Следующий сценарий выводит перечень всех доступных квалификаторов выбранного свойства выбранного класса WMI:

strComputer = "."             'имя компьютера
strNS       = "RootCIMV2"    'имя пространства имён
strClass    = "Win32_Process" 'имя класса
strProperty = "Caption"       'имя свойства
'==========================================================
'Подключение к выбранному классу WMI
Set objClass = GetObject("winmgmts:\" & strComputer & "" & strNS & ":" & strClass)
'Перебор квалификаторов свойства
For Each objQualifier In objClass.Properties_(strProperty).Qualifiers_
    If IsArray(objQualifier.Value) Then
        WScript.Echo objQualifier.Name & " = " & Join(objQualifier.Value)
    Else
        WScript.Echo objQualifier.Name & " = " & objQualifier.Value
    End If
Next

Следующий сценарий выводит перечень всех доступных квалификаторов выбранного метода выбранного класса WMI:

strComputer = "."             'имя компьютера
strNS       = "RootCIMV2"    'имя пространства имён
strClass    = "Win32_Process" 'имя класса
strMethod   = "Create"        'имя метода
'==========================================================
'Подключение к выбранному классу WMI
Set objClass = GetObject("winmgmts:\" & strComputer & "" & strNS & ":" & strClass)
'Перебор квалификаторов метода
For Each objQualifier In objClass.Methods_(strMethod).Qualifiers_
    If IsArray(objQualifier.Value) Then
        WScript.Echo objQualifier.Name & " = " & Join(objQualifier.Value)
    Else
        WScript.Echo objQualifier.Name & " = " & objQualifier.Value
    End If
Next

Создание временных потребителей событий WMI

Общие положения об обработке событий в WMI были приведены выше в разделе «Общие сведения о событиях в WMI». Здесь же будут приведены примеры скриптов, подписывающихся на события. Сценарии, являющиеся временными потребителями событий WMI, должны произвести подписку на нужные события, после чего данные сценарии начнут получать извещения о наступлении этих событий. После завершения работы временного потребителя событий ни одно из зарегистрированных в нём событий больше не обрабатывается.

Пример скрипта, обрабатывающего событие изменения состояния (запуск-останов) какой-либо службы Windows:

'подключение к пространству имён
Set objService = GetObject("winmgmts:\.RootCIMV2")
'подписка на событие изменения состояния службы
Set objEventSource = objService.ExecNotificationQuery( _
"SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Service'")
'получение извещения о событии
Set objEvent = objEventSource.NextEvent
'обработка события
If objEvent.TargetInstance.State <> objEvent.PreviousInstance.State Then
	WScript.Echo Date & " " & Time & vbCrLf & _
	             objEvent.TargetInstance.DisplayName & vbCrLf & _
	             "Текущее состояние: " & objEvent.TargetInstance.State & vbCrLf & _
	             "Предыдущее состояние: " & objEvent.PreviousInstance.State
End If

Чтобы проверить работу скрипта, запустите скрипт, а затем запустите или остановите какую-нибудь службу, например MSSQLSERVER. После запуска скрипт начнёт ожидать событие. При наступлении события скрипт обработает его и завершит работу.

Запрос на языке WQL, осуществляющий подписку на событие, выполняется с помощью специального метода ExecNotificationQuery() объекта SWbemServices. Метод возвращает ссылку на объект SWbemEventSource. Вызов метода NextEvent() объекта SWbemEventSource приводит к ожиданию события и возврату в конечном итоге объекта SWbemObject, который содержит описание события. В данном случае свойства PreviousInstance и TargetInstance этого объекта представляют из себя также объекты SWbemObject, которые описывают предыдущее и текущее состояние управляемого ресурса.

Ключевое слово «WITHIN» языка запросов WQL определяет временной интервал опроса о наступлении события (в нашем примере — 5 секунд). Ключевое слово «ISA» языка запросов WQL определяет имя целевого класса (в нашем примере — «Win32_Service»). Мы использовали в запросе класс __InstanceModificationEvent, поскольку нас интересовало событие модификации экземпляра класса (существуют также классы __InstanceCreationEvent и __InstanceDeleionEvent, отвечающие за создание и удаление экземпляра класса).

Подписка на событие была произведена в полусинхронном режиме, т.к. третий параметр метода ExecNotificationQuery() (параметр iFlags, который был опущен) имеет значение по умолчанию, равное 16+32.

Метод ExecNotificationQuery() объекта SWbemServices имеет следующий синтаксис:

ExecNotificationQuery(strQuery, [strQueryLanguage = «WQL»], [iFlags = (16+32)], [objWbemNamedValueSet = null])

Параметры:

  • strQuery — строка, текст запроса на языке WQL.
  • strQueryLanguage — язык запроса. Если задан, должен быть всегда равен «WQL».
  • iFlags — опции, комбинация флагов. Возможные значения:
    • wbemFlagReturnImmediately(16) — немедленный возврат результата (полусинхронный режим).
    • wbemFlagForwardOnly(32) — возвращает коллекцию типа forward-only (навигация только вперёд). Максимальная производительность и экономия памяти.
  • objWbemNamedValueSet — объект SWbemNamedValueSet, элементы которого представляют контекстную информацию, которая может использоваться провайдером, который обслуживает запрос. Провайдер, который поддерживает или требует такую информацию, должен документировать имена и типы данных возможных значений. Как правило, этот параметр остаётся пустым.

Обработка событий может производиться и в асинхронном режиме:

'время выполнения скрипта в секундах, после чего скрипт будет остановлен
WScript.Timeout = 3600
'подключение к пространству имён
Set objService = GetObject("winmgmts:\.RootCIMV2")
'создание объекта SWbemSink
Set objSink = WScript.CreateObject("WbemScripting.SWbemSink", "Sink_")
'подписка на событие изменения состояния службы
Call objService.ExecNotificationQueryAsync(objSink, _
"SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Service'")
'приостанавливаем выполнение сценария
While 1=1
	WScript.Sleep 1000
Wend
'**************************************************************************************************
Sub Sink_OnObjectReady(objEvent, objContext)
	If objEvent.TargetInstance.State <> objEvent.PreviousInstance.State Then
		WScript.Echo Date & " " & Time & vbCrLf & _
		             objEvent.TargetInstance.DisplayName & vbCrLf & _
		             "Текущее состояние: " & objEvent.TargetInstance.State & vbCrLf & _
		             "Предыдущее состояние: " & objEvent.PreviousInstance.State
	End If
End Sub

Работа с объектом SWbemSink и обработка его событий, а также отличия асинхронных методов (с суффиксом «Async») от «обычных» методов были рассмотрены в предыдущих разделах, поэтому здесь останавливаться на этом не будем. По вышеприведённому скрипту остаётся только добавить, что он будет обрабатывать события в течение часа, после чего его работа будет автоматически завершена.

Создание постоянных потребителей событий WMI

Общие положения об обработке событий в WMI были приведены выше в разделе «Общие сведения о событиях в WMI». Здесь же будет приведён пример скрипта, создающего постоянного потребителя событий.

Для постоянной обработки событий WMI нужно выполнить три операции:

  • Зарегистрировать нужный фильтр событий.
  • Зарегистрировать потребителя событий.
  • Установить связь между фильтром и потребителем.

Для регистрации своего фильтра событий нужно создать новый экземпляр класса __EventFilter и заполнить его свойства Query, QueryLanguage и Name. Постоянный потребитель событий должен быть представлен экземпляром одного из потомков класса __EventConsumer. В приведённом ниже скрипте создаётся экземпляр класса LogFileEventConsumer, который позволяет производить запись в текстовый файл. Установка связи между фильтром и потребителем осуществляется путём создания экземпляра ассоциативного класса __FilterToConsumerBinding. В свойства Filter и Consumer экземпляра этого класса записываются «пути» объекта-фильтра и объекта-потребителя (объекты SWbemObjectPath, хранящиеся в свойстве Path_ этих объектов). Создадим постоянного потребителя событий, который будет отслеживать изменения состояний (запуск-останов) служб Windows. Текст скрипта:

'подключение к пространству имён
Set objService = GetObject("winmgmts:\.RootCIMV2")
'создание экземпляра класса __EventFilter (фильтр событий)
Set objFilter = objService.Get("__EventFilter").SpawnInstance_()
'установка свойств фильтра событий
objFilter.Name = "MonitoringServices"
objFilter.QueryLanguage = "WQL"
objFilter.Query = "SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Service'"
'запись фильтра событий
objFilter.Put_
'создание экземпляра класса LogFileEventConsumer (потребитель событий)
Set objConsumer = objService.Get("LogFileEventConsumer").SpawnInstance_()
'установка свойств потребителя событий
objConsumer.Name = "ServiceLog"
objConsumer.FileName = "C:ServiceLog.txt"
objConsumer.Text = "Service: %TargetInstance.DisplayName%, state: %TargetInstance.State%."
'запись потребителя событий
objConsumer.Put_
'**************************************************************************************************
Set objFilter = objService.Get("__EventFilter.Name=""MonitoringServices""")
Set objConsumer = objService.Get("LogFileEventConsumer.Name=""ServiceLog""")
'создание экземпляра класса __FilterToConsumerBinding (связка)
Set objBinding = objService.Get("__FilterToConsumerBinding").SpawnInstance_()
'установка свойств связки
objBinding.Filter = objFilter.Path_
objBinding.Consumer = objConsumer.Path_
'запись связки
objBinding.Put_

В строке, записываемой в свойство Text экземпляра класса LogFileEventConsumer, присутствуют шаблонные символы «%». В место строки, ограниченное этими символами, при выполнении скрипта будут подставлены значения, возвращаемые кодом, который содержится между символами «%». Таким образом, можно сказать, что свойство Text класса LogFileEventConsumer поддерживает шаблонные символы. Примечание: если у какого-либо свойства имеется квалификатор Template со значением True, то это свойство поддерживает шаблонные символы.

Ещё одно важное замечание: по умолчанию не все стандартные классы устанавливаются в репозиторий CIM. Для использования стандартных классов постоянных потребителей (например, LogFileEventConsumer), скорее всего, придётся сначала установить их. MOF-файлы с описанием этих классов находятся в каталоге %SystemRoot%system32Wbem. Скомпилировать эти файлы можно с помощью утилиты mofcomp.exe. Пример команды компиляции:

mofcomp -N:rootcimv2 %SystemRoot%system32WbemWbemcons.mof

Текст скрипта, который удаляет фильтр событий и постоянного потребителя событий WMI, созданные в предыдущем скрипте:

'подключение к пространству имён
Set objService = GetObject("winmgmts:\.RootCIMV2")
'получение нужных экземпляров
Set objFilter = objService.Get("__EventFilter.Name=""MonitoringServices""")
Set objConsumer = objService.Get("LogFileEventConsumer.Name=""ServiceLog""")
'удаление полученных экземпляров
objFilter.Delete_
objConsumer.Delete_

Источник: http://www.script-coding.info

Только пользователи локальной группы «Администраторы» имеют право запускать WMIC.

В основе структуры данных в WBEM лежит Common Information Model (CIM), реализующая объектно-ориентированный подход к представлению компонентов системы. CIM является расширяемой моделью, что позволяет программам, системам и драйверам добавлять в неё свои классы, объекты, методы и свойства.

Важной особенностью WMI является то, что хранящиеся в нём объекты соответствуют динамическим ресурсам, то есть параметры этих ресурсов постоянно меняются, поэтому параметры таких объектов не хранятся постоянно, а создаются по запросу потребителя данных. Хранилище свойств объектов WMI называется репозиторием и расположено в системной папке операционной системы Windows:

%SystemRoot%WindowsSystem32wbemRepository

Так как WMI построен по объектно-ориентированному принципу, то все данные операционной системы представлены в виде объектов и их свойств и методов.

Все классы группируются в пространства имен, которые иерархически упорядочены и логически связаны друг с другом по определенной технологии или области управления. В WMI имеется одно корневое пространство имен Root, которое в свою очередь имеет 4 подпространства: CIMv2, Default, Security и WMI.

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

Свойства классов используются для однозначной идентификации экземпляра класса и для описания состояния используемого ресурса. Обычно все свойства классов доступны только для чтения, хотя некоторые из них можно модифицировать определенным методом. Методы классов позволяют выполнить действия над управляемым ресурсом.

Каждому экземпляру класса можно обратиться по полному пути, который имеет следующую структуру:

[ComputerNameNameSpace][: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:Domainname

 Чтобы перезагрузить компьютер

            /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-POLLROOTCIMV2:Win32_OperatingSystem.Name=»Microsoft Windows XP Professional|C:WINDOWS|DeviceHarddisk0Partition1″

 Для того чтобы запустить сервис надо (вывести список сервисов в системе)

            service list brief

            service where (name=»<имя_сервиса>») call startservice || stopservice

            /output:c:service.html service list full /format:htable

 Чтобы работало wmic, надо

            Служба WMI должна быть помещена в автозапуск, а также должно быть разрешено соединение по DCOM:

1) В разделе реестра HKLMSOFTWAREMICROSOFTOLE установите значение EnableDCOM в «Y», а также EnableRemoteConnect в «Y». Значение EnableRemoteConnect по умолчанию «N».

2) В разделе реестра HKLMSOFTWAREMicrosoftwbemcimom установите значение AutostartWin9X в «2». Установите значение EnableAnonConnections в «1».

3) Добавьте файл Winmgmt.exe в автозагрузку. Файл находится в каталоге WindowsWBEM.

Модели DCOM сопоставлен TCP-порт 135.

netsh firewall add portopening TCP 135 DCOM_TCP135

 Удаленно включаем службу удаленный рабочий стол (Remote Desktop)

             Wmic /node:»servername» /user:»[email protected]» /password:»password» RDToggle where ServerName=»server name» call SetAllowTSConnections 1

 Вывод служб которые запускают с правами LocalSystem

            /output:c:idcns.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:rootcli>/output:c:startup_full.html startup  list  full  /format:htable

wmic:rootcli>/output:c:startup_system.html startup  list  system  /format:htable

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

О наличии проблем с WMI может свидетельствовать широкий спектр ошибок:

  • Ошибки обработки WMI запросов в системных журналах и логах приложений (
    0x80041002 - WBEM_E_NOT_FOUND
    ,
    WMI: Not Found
    ,
    0x80041010 WBEM_E_INVALID_CLASS
    );
  • Ошибки обработки GPO, связанные на WMI ( некорректная работа wmi фильтров групповых политик, и пр.);
  • WMI запросы выполняются очень медленно;
  • Ошибки при установке или работе агентов SCCM/SCOM;
  • Ошибки в работе скриптов (vbs или PowerShell), использующих пространство имен WMI (скрипты с Get-WmiObject и т.д.).

Содержание:

  • Диагностика проблем с WMI
  • Исправление WMI репозитория, перерегистрация библиотек, перекомпиляция MOF файлов
  • Сброс и пересоздание WMI репозитория (хранилища)

Диагностика проблем с WMI

В первую очередь нужно проверить служба Windows Management Instrumentation (Winmgmt) установлена в Windows и запущена. Вы можете проверить состояние службы в консоли services.msc или с помощью PowerShell:

Get-Service Winmgmt | Select DisplayName,Status,ServiceName

служба Windows Management Instrumentation (Winmgmt) работает

Если служба Winmgmt запущена, вы можете проверить работоспособность WMI, обратившись к ней с помощью простого WMI-запроса. Вы можете выполнить wmi запрос из командной строки или из PowerShell. Например, следующая команда выведет список установленных в Windows программ:

wmic product get name,version

Простейшая PowerShell команда для получения информации о версии и билда Windows 10 через WMI может выглядеть так:

get-wmiobject Win32_OperatingSystem

powershell проверка работы wmi командой get-wmiobject

Как вы видите, служба WMI ответила на запрос корректно. Если при выполнении такого WMI-запроса Windows возвращает ошибку, скорее всего сервиса WMI работает некорректно, поврежден WMI репозиторий или есть какие-то другие проблемы.

ошибка Failed to initialize all required WMI classes

В моем случае, например, при открытии свойств WMI Control в консоли управления компьютером (compmgmt.msc) появлялась надпись:

Failed to initialize all required WMI classes
Win32_Processor. WMI: Invalid namespace
Win32_WMISetting. WMI: Invalid namespace
Win32_OperationSystem. WMI: Invalid namespace

Ранее для диагностики WMI существовала официальная утилита от Microsoft – WMIDiag.vbs (Microsoft WMI Diagnosis). WMIdiag это vbs скрипт, который проверяет различные подсистемы WMI и записывает собранную информацию в лог файлы (по умолчанию логи находятся в каталоге %TEMP% — C:USERS%USERNAME%APPDATALOCALTEMP). Получившийся отчет состоит из файлов, имена которых начинаются с WMIDIAG-V2.2 и включает в себя следующие типы фалов:

  • .log файлы содержат подробный отчет об активности и работе утилиты WMIDiag;
  • .txt файлы содержат итоговые отчеты о найденных ошибках, на которые стоит обратить внимание;
  • В .csv файлах содержится информация, нужная для долгосрочного анализа работы подсистемы WMI.

скрипт для исправления ошибок WMI WMIDiag.vbs

Совет. В 64 битных версиях Windows wmidiag нужно запускать так:

c:windowsSystem32cscript.exe wmidiag.vbs

в противном случае появится ошибка:

WMIDiag must be run from native 64-bit environment. It is not supported in Wow64.

WMIDiag It is not supported in Wow64

После окончания работы утилиты WMIDiag администратор должен изучить полученные файлы логов, проанализировать и попытаться исправить найденные ошибки.

К сожалению, последняя версия WMIDiag 2.2 корректно работает только с версиями до Windows 8.1/Windows Server 2012 R2. На данный момент Microsoft даже удалила ссылку на загрузку WMIDiag из Download Center. Но при желании, этот скрипт можно найти в сети.

WMIDiag может дать подробную информацию по исправлению частных ошибок в WMI, но в большинстве случаев процесс это довольно трудоемкий и стоит потраченного времени только при решении инцидентов в критичных системах (как правило, на продуктивных серверах). Для массового сегмента рабочих станций пользователей сбросить и пересоздатьWMI репозиторий в Windows.

Исправление WMI репозитория, перерегистрация библиотек, перекомпиляция MOF файлов

В Windows 10/Windows Server 2016 вы можете проверить целостность репозитория WMI с помощью команды:

winmgmt /verifyrepository

winmgmt-verifyrepository - проверка состояния репозитория wmi

Если команда возвращает, что база данных WMI находится в неконсистентном состоянии (INCONSISTENT или WMI repository verification failed), стоит попробовать выполнить “мягкое” исправление ошибок репозитория:

Winmgmt /salvagerepository

WMI repository has been salvaged.

Данная команда выполняет проверку согласованности хранилища WMI и при обнаружении несогласованности перестраивает базу данных WMI.

Перезапустите службу WMI:

net stop Winmgmt
net start Winmgmt

Если стандартный способ исправления ошибок в WMI не помог, попробуйте следующий скрипт. Данный скрипт представляет собой ”мягкий” вариант восстановления службы WMI на компьютере (выполняется перерегистрация dll библиотек и службы WMI, перекомпилируются mof файлы). Данная процедура является безопасной и ее выполнение не должно привести к каким-либо новым проблемам с системой.

sc config winmgmt start= disabled
net stop winmgmt
cd %windir%system32wbem
for /f %s in ('dir /b *.dll') do regsvr32 /s %s
wmiprvse /regserver
sc config winmgmt start= auto
net start winmgmt
for /f %s in ('dir /b *.mof') do mofcomp %s
for /f %s in ('dir /b *.mfl') do mofcomp %s

На 64 битной версии Windows эти действия нужно также выполнить для каталога SysWOW64. Замените третью строку на

cd %windir%SysWOW64wbem

bat скрипт для перерегистрации компонентов wmi

Указанные команды можно выполнить путем простой вставки в окно командой строки, либо сохранить код в bat файле wmi_soft_repair.bat и запустить его с правами администратора. После окончания работы скрипта, перезагрузите Windows и проверьте работу WMI.

Сброс и пересоздание WMI репозитория (хранилища)

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

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

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

Следующая команда выполнит сброс базы данных WMI к исходному состоянию (как после чистой установки Windows). Используйте эту команду для выполнения hard reset репозитория WMI, если параметре salvagerepository не исправил проблему:

Winmgmt /resetrepository

Совет. На практике бывают случаи, когда пересоздание хранилища WMI приводит к проблемам со сторонним софтом. Это связано с тем, что все записи в базе WMI обнуляются (до состояния чистой системы). Такие программы скорее всего, придется переустанавливать в режиме восстановления.

Если обе команды (
Winmgmt /salvagerepository
и
Winmgmt /resetrepository
) не восстановили консистентное состояние базы WMI, попробуйте выполнить “жесткое” пересоздание базы WMI вручную таким скриптом:

sc config winmgmt start= disabled
net stop winmgmt
cd %windir%system32wbem
winmgmt /resetrepository
winmgmt /resyncperf
if exist Repos_bakup rd Repos_bakup /s /q
rename Repository Repos_bakup
regsvr32 /s %systemroot%system32scecli.dll
regsvr32 /s %systemroot%system32userenv.dll
for /f %s in ('dir /b *.dll') do regsvr32 /s %s
for /f %s in ('dir /b *.mof') do mofcomp %s
for /f %s in ('dir /b *.mfl') do mofcomp %s
sc config winmgmt start= auto
net start winmgmt
wmiprvse /regserver

сброс и восстановление хранилища wmi в windows 10

На 64 битной версии Windows нужно также перерегистрировать dll/exe и перекомпилировать mof файлы в каталоге %windir%sysWOW64wbem.

Данный скрипт полностью пересоздает хранилище WMI (старый репозиторий сохраняется в каталог Repos_bakup). После окончания работы скрипта нужно перезагрузить Windows. Затем протестируйте работу службы WMI простым запросом.

Проверьте состояние WMI репозитория. Если ошибки исправлены, команда
winmgmt /verifyrepository
должна вернуть:

WMI repository is consistent

WMI repository is consistent

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

Наверняка еще с незапамятных времен, в операционной системе 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%System32Wbem. В разных версиях операционной системы 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_MACHINESoftwareMicrosoftWBEM

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%System32Wbem.

В то время как служба WMI обслуживает управляющие приложения через COM-интерфейс, WMI-провайдеры действуют в качестве COM-серверов, обрабатывающих запросы от службы WMI. Когда провайдер загружается, он регистрирует собственное положение и классы, объекты, свойства, методы и события, которые он предоставляет [в WMI]. WMI использует эту информацию для перенаправления запросов к соответствующему провайдеру. Так же взаимодействие между разными участниками WMI может происходить:

  • локально — через COM-интерфейс;
  • удаленно — через DCOM-интерфейс или [более современный] Windows Remote Management (WinRM).

WMI обрабатывает запросы от управляющих приложений следующим образом:

  1. [Управляющее] приложение отправляет запрос к WMI, которая, в свою очередь, перенаправляет его к соответствующему провайдеру (поставщику).
  2. Провайдер выполняет взаимодействие с запрошенным системным ресурсом и возвращает результат к WMI.
  3. WMI передает ответ [обратно] к вызвавшему приложению. Ответ может быть актуальными данными [запрашиваемого] ресурса или результатом выполнения [требуемой] операции.

WMI структура

Microsoft предлагает некоторое количество «встроенных» провайдеров в составе дистрибутива операционной системы Windows: журнала событий, системного реестра, файловой системы и некоторых других.

Репозиторий (хранилище)

Как было сказано выше, WMI базируется на том, что информация о состоянии любого управляемого объекта может быть представлена в виде общей информационной модели (CIM), которая сама по себе фактически и является хранилищем объектов и классов, моделирующих различные компоненты компьютерной системы. Таким образом, в общем случае:

Репозиторий CIM — хранилище модели CIM.

или более адаптированно для реалий операционной системы:

WMI (CIM) Репозиторий — это дисковая база данных, используемая для хранения «откомпилированного представления» объектов WMI (определений классов и экземпляров пространств имен) и обеспечивающая эффективный (оптимизированный) доступ к ним.

Где класс выступает в качестве модели (шаблона) управляемого объекта (фактически любого компонента операционной системы: процесса, сервиса, файловой системы, события, диска и многого другого). В файловой системе репозиторий располагается по пути: %SystemRoot%System32WbemRepository и состоит из следующих файлов (для 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-языке], описывающие пространство имен RootSMS и содержащиеся в нем классы. MOF использует синтаксис C++ и предоставляет [своеобразный] шаблон для описания WMI-объекта. В то время, как WMI-провайдеры генерируют неструктурированные данные, MOF-файлы представляют шаблоны, в которых сгенерированные данные форматированы.

Классы и пространства имен WMI

Классы WMI сгруппированы в пространства имен (namespaces), которые выстроены иерархически в виде дерева (с единым корнем) и напоминают используемые в традиционных объектно-ориентированных языках программирования.

Пространство имен WMI – это группировка (контейнер) классов и объектов, объединенных по назначению, то есть относящихся к определенной технологии или области управления.

Вне зависимости от версии WMI в системе имеется несколько предопределенных пространств — корневое пространство имён Root, и 4 пространства, располагающихся уровнем ниже: CIMv2, Default, Security и WMI. Все пространства имен являются производными от КОРНЕВОГО (Root) пространства имен. Пространства имен организуют в себе классы WMI и другие элементы, таким образом их проще представить себе в качестве контейнера или каталога файловой системы. Некоторые пространства имен содержат вложенные пространства имен, и так далее. Классы объектов WMI распределены иерархически в пространства имен, похожих на используемые в традиционных объектно-ориентированных языках программирования. Одно из существующих в Windows пространств имен назначается пространством по умолчанию, в стандартной поставке им является пространство имен RootCIMV2. Таким образом, при запросах объектов, в которых явно не задано пространство имен, будем выбрано пространство по умолчанию.

Язык запросов 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, выполните следующие действия:

  1. ПускАдминистрирование и выберите пункт Управление компьютером;
  2. Разверните узел Службы и приложения и щелкните правой кнопкой мыши элемент управления WMI;
  3. Правая кнопка мыши → выберите пункт меню Свойства, чтобы открыть диалоговое окно Свойства элемента управления WMI;
  4. Перейдите на вкладку Безопасность и разверните корневой узел Root. Выберите требуемый объект пространства имен (установив курсор), затем нажмите кнопку Безопасность;

Отладка/запись событий WMI

Похоже в ранних реализациях настройка журнала событий WMI находилась в свойствах элемента управления WMI, однако в новых версиях её перенесли в общий Просмотр событий.

  1. Открыть Просмотр Событий (Event Viewer, Eventvwr).
  2. В меню Вид, выбрать Отобразить аналитический и отладочный журналы.
  3. В дереве в левом фрейме разворачиваем пункт Журналы приложений и служб (Applications and Service Logs) → Microsoft → Windows → WMI Activity
  4. Правую кнопку мыши на пункте Trace и выбираем Включить журнал (Enable Log). Если выбрать Свойства из того же меню, то можно увидеть куда пишутся события трассировки: %SystemRoot%System32WinevtLogsMicrosoft-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:

  1. Ошибки в log-файлах самих приложений: WBEM_E_NOT_FOUND — 0x80041002.
  2. Ошибки отказа при подключении к пространствам имен RootDefault или Rootcimv2;
  3. Ошибка/подвисание при открытии свойств WMI в оснастке Управление компьютером: «WMI : Not Found», «0x80041010 WBEM_E_INVALID_CLASS», «Filed to initialize all required WMI classes»;
  4. Подвисание разных утилит по работе с WMI (wbemtest и прч);
  5. Отсутствие в репозитории некоторых схем/классов/объектов;
  6. Проблема в запуске SCCM-агента (WBEM_E_INVALID_CLASS — 0x80041010);
  7. Ошибки подключения/операций (0x8007054e);
  8. Ошибки подгрузки WMI-провайдеров: WBEM_E_PROVIDER_LOAD_FAILURE — 0x80041013;
  9. Ошибки доступа при попытке доступа к WMI-объектам: E_ACCESS_DENIED — 0x80070005;
  10. Ошибки поиска пространств имен: WBEM_E_INVALID_NAMESPACE — 0x8004100E;
  11. Ошибки в Журнале событий Windows (Приложение) — источник WinMgmt, EventID — 10;

Восстановление WMI

Доступный на данный момент в системе/Сети инструментарий диагностических инструментов WMI даёт возможность довольно скрупулезно подойти в вопросу восстановления работоспособности WMI, но кто бы еще так же детально (тонко) этот WMI понимал, так что процесс этот довольно трудоемкий. Поэтому поступают проще и обычно используют основные методы:

  1. Набор действий по восстановлению репозитория через утилиты командной строки;
  2. [многочисленные] скрипты по восстановлению репозитория/перекомпиляции mof/mfl, перерегистрации провайдеров;

Эти методики подходят для большинства ситуаций, которые могут встретиться на рабочих станциях пользователей/серверах. Тем не менее, имеется несколько тонких моментов в логике восстановления работоспособности WMI, и их нужно непременно усвоить:

  1. Самым примитивным способом восстановления репозитория является удаление/переименование его рабочей директории. То есть, вы переименовываете директорию %SystemRoot%System32WbemRepository, к примеру, в Repository.old и ждете. После определенного таймаута сервис определит отсутствие директории репозитория и запустит процедуру восстановления. Но этот простой способ особенно никем не применяется, поскольку не учитывает перекомпиляцию не входящих в автовосстановление (список .mof в реестре) классов и не выполняет перерегистрацию провайдеров.
  2. Вне зависимости от того, где и как оно применяется, удаление рабочего WMI-репозитория является достаточно разрушительной операцией, которая может повлечь за собой потерю данных, возникновение ошибок в WMI-приложениях, замедление отклика некоторых операций, и возникновении других, сложнодиагностируемых проблем.
  3. Существуют приложения, которые в процессе установки в систему [самостоятельно] напрямую обновляют репозиторий, вообще не используя никаких .mof-файлов. Соответственно, при пересоздании (удалении и создании) репозитория подобные приложения не имеют возможности обновить базу данных и их данные, связанные с WMI, будут удалены (потеряны) вплоть до момента, пока вы не переустановите означенные приложения (в режиме восстановления).
  4. Следует помнить, что не все приложения хранят свои WMI-провайдеры (.dll) и .mof-файлы в %SystemRoot%System32wbem. Соответственно, вам нужно будет выявить подобные приложения (поиск по маске *.mof), и либо произвести их переустановку, либо выполнить ручную регистрацию провайдеров (библиотек) и перекомпиляцию .mof-файлов.
  5. Существуют .mof-файлы, которые содержат директивы вида #pragma deleteclass или #pragma deleteinstance. По хорошему, некоторые источники советуют временно перемещать подобные файлы в стороннюю директорию перед потоковой перекомпиляцией всех .mof-файлов. Но никто этого делать не хочет, ну и мы не будем.
  6. [ начиная с Windows7 ] в каталоге репозитория можно обнаружить файлы, содержащие информацию об удалении, такие как OfflineFilesWmiProvider_Uninstall.mof, Wdf01000Uninstall.mof, Win32_EncryptableVolumeUninstall.mof, WinsatUninstall.mof, wpcuninst.mof, WsmAgentUninstall.mof, WUDFxUninstall.mof, в именах которых присутствует слово uninstall. И если скрипты перечисляют и компилируют все без исключения файлы, то компиляция подобных файлов приведет к удалению классов, соответственно последние станут недоступны. Но эту проблему можно обойти путем исключения.
  7. Перекомпиляция MOF-файлов зачастую должна производиться в определенной последовательности. Например, классы в файле [условно] 1.mof могут зависеть от классов, указанных в файле 2.mof. Если последние отсутствуют, утилита mofcomp.exe не будет добавлять классы. Для того, что бы подобрать правильную последовательность, нужно знать зависимости для всех классов, представленных в системе. Возможно эту проблему можно частично решить перекомпиляцией каких-то базовых (основных) .mof-файлов в первую очередь, перед основным циклом перекомпиляции всех остальных. Поэтому скрипты на данный момент не делают всё идеально, но все-равно даже это работает и приносит результат :)
  8. Везде встречаются рекомендации о том, что сперва надо компилировать .mof-файлы, а затем уже их локализованные .mfl-копии. Когда все файлы размещались в одной директории, было удобно, но в последних версиях ОС .mfl переехали в локализованные поддиректории (например, ru-RU), поэтому проход по *.mfl надо делать с учетом вложенных директорий?
  9. Имеются рекомендации, что в 64-битных ОС работу ручную перекомпиляцию репозитория надо выполнять из директории %SystemRoot%SysWOW64wbem, а на 32-битных системах из %SystemRoot%System32wbem, но оказалось, что (в ОС, начиная с 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%System32wbem

$WBEM = «${Env:Windir}System32wbem»

Set-Location -Path $WBEM

# Остановка сервиса WMI

$WMIService = Get-Service -Name «Winmgmt»

$WMIService | Stop-Service -Force -Verbose

Start-Sleep -seconds 1

# Переименование существующей директории репозитория

if (Test-Path «$WBEMRepository») {

      Write-Host «Renaming WBEM Repository…»

      if (Test-Path «$WBEMrepository.bak») { Remove-Item «$WBEMrepository.bak» -Force -Recurse -Confirm:$false }

      Rename-Item -Path «$WBEMrepository» -NewName «$WBEMrepository.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), которые производят переименование текущего репозитория.

Понравилась статья? Поделить с друзьями:
  • Windows media center windows 10 home
  • Windows management instrumentation service по русски
  • Windows media center tv pack 2008
  • Windows management instrumentation service subsystems initialized successfully
  • Windows media center extender скачать для windows