Инструментарий WMI живёт в Windows дольше многих администраторов: это огромная база управляющих классов, через которую система отдаёт сведения о процессоре, дисках, службах, событиях и почти обо всём остальном. Запрос к ней умещается в одну строку командной строки, и поэтому связка wmic плюс пара фильтров десятилетиями оставалась самым быстрым способом ответить на вопрос "а что вообще стоит в этой машине" без установки агентов. Статья разбирает, как устроена база CIM-классов, как строить запросы на WQL, где подстерегают ограничения вроде фиктивных температурных датчиков, и как собрать из консольных запросов простого сторожа здоровья дисков с уведомлением при превышении порога.
База классов CIM и самые полезные представители
WMI - это реализация стандарта CIM (Common Information Model): сведения хранятся не таблицами в привычном смысле, а экземплярами классов, разложенными по пространствам имён. Основной "склад" для админа - namespace root\cimv2, именно туда попадает запрос, если явно ничего не указать. Класс Win32_Processor отдаёт модель, тактовую частоту, число ядер и загрузку; Win32_OperatingSystem - редакцию системы, время аптайма, свободную память; Win32_LogicalDisk - буквы томов, размеры и свободное место; Win32_DiskDrive - физические диски с серийными номерами и моделями; Win32_NetworkAdapterConfiguration - адреса и шлюзы. Всё это читается единым образом: выбрали класс, перечислили нужные свойства, получили результат.
Класс Win32_TemperatureProbe выглядит заманчиво, но на практике почти всегда пуст. Реальные температуры процессора через стандартный WMI получить трудно: есть класс MSAcpi_ThermalZoneTemperature в пространстве имён root\wmi, однако на большинстве современных машин он возвращает статическое значение, прошитое прошивкой, а не живые показания датчиков. Причина проста - драйвера ACPI отдают туда данные лишь на ограниченном наборе плат, а вендорский мониторинг реализован через собственные драйверы вроде тех, с которыми работают LibreHardwareMonitor или утилита производителя платы. Вывод для практики: настоящий температурный контроль через WMI строят на показаниях системы охлаждения серверных платформ, где производитель установил свой WMI-провайдер, либо ограничиваются косвенными сигналами. А вот здоровье дисков WMI отдаёт честно, и на этом стоит строить сторожа.
Синтаксис wmic и быстрые выборки
Утилита wmic - тонкая обёртка над запросами, вызываемая прямо из cmd. Классический пример инвентаризации дисков: wmic logicaldisk get size,freespace. Команда выводит таблицу с размером и свободным местом в байтах для всех букв томов. Добавив фильтр, можно сузить выборку: wmic logicaldisk where "drivetype=3" get deviceid,size,freespace - только локальные фиксированные диски. Условие where здесь - не изобретение утилиты, а проброшенный внутрь кусок языка WQL, поэтому внутри работают сравнения, AND и OR, а строки берутся в двойные кавычки, чтобы не поссориться с cmd.
Полезные готовые формы: wmic cpu get name,maxclockspeed,loadpercentage - процессор и его загрузка; wmic os get caption,lastbootuptime,freephysicalmemory - система и аптайм; wmic diskdrive get model,serialnumber,status - физические диски и их статус; wmic bios get serialnumber - серийный номер шасси для учётной ведомости. Вывод легко перенаправить в файл или разобрать в bat-скрипте через for /f. Ключ /namespace:\\root\\cimv2 указывает пространство имён явно; по умолчанию используется именно оно, но при обращении к root\wmi или root\securitycenter2 ключ обязателен: wmic /namespace:\\root\\wmi path MSStorageDriver_FailurePredictStatus get instanceName,predictfailure. Обратные слеши в пути удваиваются, потому что wmic иначе спотыкается о разбор аргументов.
Get-CimInstance как преемник и переходный период
Утилиту wmic объявили устаревшей ещё в середине десятых годов, а начиная со сборок Windows 11 2024-2025 годов её физически убрали из системы: сначала превратили в отключаемый компонент, затем перестали ставить по умолчанию. Скрипты, написанные за эти годы, продолжают работать на старых машинах, но новую автоматизацию на wmic строить уже нельзя - рано или поздно строка просто не найдёт исполняемый файл.
Замена - командлет Get-CimInstance в PowerShell. Переписывание обычно механическое: wmic logicaldisk get size,freespace превращается в Get-CimInstance Win32_LogicalDisk | Select-Object Size,FreeSpace, а условие where переезжает в параметр -Filter, принимающий тот же WQL: Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID,Size,FreeSpace. Формально есть ещё Get-WmiObject, но он старой ветки и тоже считается устаревшим; CIM-командлеты умеют удалённые вызовы по WSMan, что быстрее и современнее ветхого DCOM. Для стажа важно одно: логика запросов, классы и фильтры не изменились - меняется лишь обёртка. Поэтому знания про Win32_-классы, накопленные на wmic, переносятся на PowerShell целиком, и сторож из этой статьи легко переписать на Get-CimInstance, когда придёт время убрать последние bat-файлы.
Сторож здоровья дисков из консольных запросов
Практический сценарий статьи: сторож, который периодически опрашивает состояние дисков и сообщает администратору, если что-то пошло не так. Первая линия обороны - свойство Status класса Win32_DiskDrive: в норме там "OK", а любое иное значение уже повод копать. Вторая, более серьёзная линия - SMART-предсказание отказа через класс MSStorageDriver_FailurePredictStatus в root\wmi: свойство PredictFailure, равное истине, означает, что контроллер диска сам сообщает о приближении отказа, а массив Reason уточняет причину. Простейший сторож на PowerShell выглядит коротко:
- Раз в пять минут выполняется Get-CimInstance -Namespace root\wmi -ClassName MSStorageDriver_FailurePredictStatus и фильтруются экземпляры с PredictFailure -eq $true.
- Параллельно опрашивается Get-CimInstance Win32_DiskDrive, и экземпляры со Status, отличным от "OK", попадают в тот же список проблем.
- Дополнительно проверяется свободное место: Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" с порогом, например, десять процентов от Size.
- Найденные нарушения собираются в текст с именем хоста, моделью диска и причиной.
- Текст уходит уведомлением: msg * "текст" для локальной сессии, toast-уведомление через модуль BurntToast для современного центра уведомлений или сообщение на почтовый ящик дежурного - в зависимости от того, где администратор реально сидит.
Такой цикл кладут в планировщик задач с запуском от SYSTEM, и получается лёгкий мониторинг без единого установленного агента. Температуру сюда при желании добавляют через вендорский провайдер, если он есть, но честнее признать: на типовых машинах дисковый SMART - это тот максимум достоверной телеметрии, который WMI отдаёт без сторонних драйверов.
Язык WQL и слежение за событиями
WQL - подмножество SQL, заточенное под классы WMI. Работают SELECT со списком свойств или звёздочкой, FROM с именем класса, WHERE с простыми сравнениями и логикой; не работают JOIN, подзапросы и агрегаты сложнее банального Count - связанные данные собирают двумя запросами или через ассоциаторы. Пример: SELECT DeviceID, FreeSpace FROM Win32_LogicalDisk WHERE DriveType = 3 AND FreeSpace < 10737418240 вернёт локальные тома, где осталось меньше десяти гигабайт.
Самая недооценённая часть WQL - событийные запросы. Конструкция SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA "Win32_Process" с подсказкой WITHIN просит WMI раз в десять секунд проверять, не появился ли новый процесс. Аналогично __InstanceDeletionEvent ловит завершение, __InstanceModificationEvent - изменение свойств, например, переход службы Win32_Service в состояние Stopped. В PowerShell это подписывается через Register-CimIndicationEvent и превращается в реактивный сторож: вместо опроса по таймеру система сама присылает событие. Плата за удобство - тот же опрос под капотом: маленький WITHIN грузит провайдера частыми выборками, поэтому интервал выбирают по здравому смыслу, а не по желанию реагировать мгновенно.
Производительность, ремонт репозитория и удалённый доступ
WMI редко бывает молниеносным, и причины структурные. Часть классов - не таблицы, а живые вызовы провайдеров: запрашивая Win32_Process, вы каждый раз заставляете провайдер процессов заново собирать список. Условие по несуществующему индексу превращается в полный перебор экземпляров. Сам репозиторий - папка repository в wbem - представляет собой базу с историей, и разросшийся или подпорченный репозиторий делает медленными даже простые запросы. Отсюда правила: запрашивать только нужные свойства, а не звёздочку; фильтровать на стороне провайдера параметром -Filter, а не Where-Object после выборки; не опрашивать тяжёлые классы чаще, чем раз в минуту.
Развалившийся репозиторий - причина странных ошибок вроде возврата пустых результатов. Диагностика встроенная: winmgmt /verifyrepository проверяет целостность базы и отвечает, согласована она или нет. При расхождении есть winmgmt /salvagerepository, пытающийся сшить базу с сохранением данных, и крайний вариант winmgmt /resetrepository, перестраивающий её с нуля; перед сбросом службу winmgmt останавливают, а старый repository переименовывают на всякий случай. На сервере перед сбросом стоит убедиться, что никакое прикладное ПО не хранило в репозитории своих постоянных подписок.
Удалённые запросы через wmic /node:"srv01" или Get-CimInstance -ComputerName srv01 упираются в DCOM и права. Нужны: членство в локальных администраторах удалённой машины, разрешённый в брандмауэре набор правил WMI, согласованная политика DCOM. Старый DCOM ходит по эфемерным портам и капризничает за файрволами; CIM-сессии по WSMan заметно дружелюбнее к сетевой периметру, что ещё один аргумент за переход на Get-CimInstance. Учётные данные передаются параметром -Credential, и хранить пароль в скрипте открытым текстом - плохая привычка; надёжнее запускать сторожа от gMSA или выделенной учётной записи с минимально нужными правами.
Безопасность постоянства через WMI и аудит против него
Та же событийная подсистема, что делает WMI удобным для мониторинга, исторически привлекает злоумышленников: связка фильтра события и потребителя, запускающего скрипт или команду, позволяет закрепиться в системе без служб, задач планировщика и записей в автозагрузке - механизм называют WMI persistence. Разбирать его варварскую кухню здесь не нужно; администратору важно знать, где искать следы. Постоянные подписки живут в root\subscription: классами __EventFilter, __EventConsumer и связкой __FilterToConsumerBinding. Регулярная ревизия этих классов через Get-CimInstance -Namespace root\subscription -ClassName __EventConsumer - несложная и эффективная проверка: на чистой системе там обычно пусто или сидят только подписки известного ПО.
Защита строится слоями. Ограничить права: создавать потребителей событий может лишь администратор, поэтому гигиена привилегий бьёт по проблеме в корень. Включить аудит: события создания классов WMI фиксируются журналом Microsoft-Windows-WMI-Activity/Operational и Sysmon с соответствующей конфигурацией; алерт на появление новых потребителей отлавливает технику в момент установки. Подписать скрипты и включить Script Block Logging в PowerShell - тогда даже легитимно оформленная подписка оставит в журнале своё тело. И наконец, сам факт, что wmic исчезает из новых сборок, закрывает часть старых сценариев, где утилита служила безфайловым исполнителем. Зрелый подход к WMI - это не "выключить страшную штуку", а опрашивать нужные классы, следить за подписками на события и держать репозиторий здоровым: тогда база CIM остаётся тем, чем задумана, - удобным окном внутрь системы.