Статьи

PHP и WMI — копаться в Windows с PHP

Существует много устройств (серверов, настольных компьютеров, ноутбуков, планшетов, телефонов и т. Д.), Работающих под управлением операционной системы Windows. Многие из нас, кто живет в мире, основанном на nix, должны работать в этой ОС, а если нет, то рано или поздно. Помимо обычных инструментов, которые мы можем ожидать от системы * nix (скажем, Apache, PHP, MySQL, C / C ++ и т. Д.), Windows предлагает набор уникальных функций, которых нет ни в одной другой ОС, и WMI является одной из них.

В этой статье мы рассмотрим следующие вопросы: что такое WMI? Как использовать WMI с PHP? У нас будет несколько минимальных примеров кодов, чтобы пройти основные приемы программирования.

Что такое WMI и почему мы должны с ним бороться

Сайт MSDN имеет официальное определение WMI в этой статье , из которой несколько строк извлечены ниже:

Инструментарий управления Windows (WMI) — это реализация Microsoft Web-Based Enterprise Management (WBEM), которая является отраслевой инициативой по разработке стандартной технологии доступа к информации управления в корпоративной среде.

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

WMI предоставляет исчерпывающие знания о машине, как аппаратном, так и программном. У него есть так называемая CIM ( общая информационная модель ) для инкапсуляции информации объектно-ориентированным способом. Он также предоставляет несколько программных интерфейсов для извлечения упомянутой информации. В чистой среде Windows это будут языки PowerShell , VB Script и .NET. Но в нашем случае это будет PHP.

Один из фундаментальных вопросов при программировании с WMI: какая «информация» доступна? Другими словами, какие объекты / классы доступны? К счастью, Microsoft предоставляет полный список того, что предлагает WMI с точки зрения классов и их свойств. Пожалуйста, посетите здесь для полной справки. В программировании WMI большую часть времени мы имеем в виду классы Win32 .

Предпосылки

На хост-компьютере Windows должен быть установлен WMI для обеспечения CIM. По умолчанию в любой системе Windows, более новой, чем Windows XP, должен быть установлен и включен WMI.

Мы можем убедиться, что это так, выполнив следующие два шага:

  1. Запустите « Computer Management » на вашем компьютере с Windows и посмотрите, работает ли служба под названием « Windows Management Instrumentation ». Если нет, запустите этот сервис.
  2. Запустите « wbemtest » в окне командной строки. Появится диалоговое окно « Windows Management Instrumentation Test ». Многие кнопки в этом диалоговом окне в настоящее время отключены, но мы можем нажать кнопку « Connect... », чтобы вызвать новое диалоговое окно, подобное показанному ниже:

Обычно нам не нужно ничего менять. root\cimv2 — это встроенное в систему пространство имен для нашего интерфейса WMI. Просто нажмите кнопку « Connect » в этом диалоговом окне. Это вернет нас к предыдущему окну со всеми включенными кнопками.

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

В брандмауэре Windows выберите « Advanced Settings », а затем включите правила входящего и исходящего доступа для записей, связанных с WMI. Пожалуйста, смотрите скриншоты ниже.

После того, как мы включим правила брандмауэра WMI на удаленном компьютере, мы можем проверить соединение, как показано на шаге 2 выше. Чтобы подключиться к удаленному компьютеру, нам нужно добавить префикс пространства имен по умолчанию (« root\cimv2 ») к IP-адресу или имени ПК, к которому нужно подключиться (« \\192.168.1.2\root\cimv2 например») и предоставить имя пользователя и пароль для этого удаленного компьютера.

Расширение PHP для WMI (.NET)

Чтобы использовать WMI (или, точнее, функциональность .NET) в PHP, нам нужно включить php_com_dotnet.dll . Добавьте одну строку в php.ini следующим образом:

 extension=php_com_dotnet.dll 

и перезапустите веб-сервер.

Примечание: php_com_dotnet.dll является расширением только для Windows. Это означает, что нам придется запускать PHP-файл, вызывающий WMI, в среде, подобной WAMP, а не в среде * nix. И, конечно же, машины, которыми мы будем управлять через WMI, должны быть основаны на Windows.

Дальнейший взгляд на то, что обеспечивает WMI

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

Мы можем ожидать, что WMI предоставит информацию о BIOS, процессоре, дисках, использовании памяти и т. Д. Но как эта информация представлена?

Помимо wbemtest официальных документов, давайте снова wbemtest диалог wbemtest и подключимся к нашему локальному компьютеру. В диалоговом окне « WMI Tester » нажмите кнопку « Enum Classes... и откройте следующее диалоговое окно:

В этом диалоговом окне ничего не вводите в текстовое поле, выберите « Recursive и нажмите « OK . Это должно вызвать другой диалог, как это:

Это очень длинный список (1110 объектов на моем ПК с Windows 8.1). Ваш ПК может выдавать другой список, но он должен быть примерно таким же, как этот. Пожалуйста, найдите время, чтобы просмотреть его и посмотреть на названия классов, которые предоставляет WMI. Например, на изображении выше мы выделили класс Win32_LogicalDisk . Он содержит всю информацию, относящуюся к логическим дискам машины. Чтобы получить более глубокое представление о том, что предлагает этот класс, дважды щелкните этот класс, и появится другое диалоговое окно Object editor :

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

Классы WMI Win32 имеют много записей для просмотра. Некоторые из наиболее часто используемых:

  • Классы компьютерной системы, включая устройство охлаждения, устройство ввода (клавиатура, мышь и т. Д.), Запоминающее устройство, материнская плата, сетевое устройство, печать, видео и монитор и т. Д.
  • Классы установленных приложений, включая шрифт и т. Д.
  • Классы операционной системы, включая драйверы, память, процессы, реестр, пользователей и т. Д.
  • Классы счетчиков производительности, включая все классы, связанные с производительностью.
  • и т. д.

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

Программирование WMI на PHP

Ниже приведен фрагмент кода с основной информацией о логических дисках удаленного компьютера с IP 192.168.1.4:

 <?php $pc = "192.168.1.4"; //IP of the PC to manage $WbemLocator = new COM ("WbemScripting.SWbemLocator"); $WbemServices = $WbemLocator->ConnectServer($pc, 'root\\cimv2', 'your account', 'your password'); $WbemServices->Security_->ImpersonationLevel = 3; $disks = $WbemServices->ExecQuery("Select * from Win32_LogicalDisk"); foreach ($disks as $d) { $str=sprintf("%s (%s) %s bytes, %4.1f%% free\n", $d->Name,$d->VolumeName,number_format($d->Size,0,'.',','), $d->FreeSpace/$d->Size*100.0); echo $str; } 

В моей системе выше будет распечатано что-то вроде:

 C: (System) 104,864,059,392 bytes, 60.4% free D: (Data) 209,719,963,648 bytes, 84.3% free E: (Misc) 185,521,188,864 bytes, 95.3% free 

Это очень простой пример, но он излагает фундаментальную структуру и ход программы PHP WMI.

Во-первых, создается экземпляр объекта COM типа WbemScripting.SWbemLocator .

Тогда соединение с ПК будет установлено методом ConnectServer . Четыре параметра для этого вызова метода говорят сами за себя. Наконец, нам нужно установить олицетворение безопасности на должном уровне. Уровень 3 является рекомендуемым уровнем для сценариев WMI. Подробное объяснение уровня задокументировано здесь . Уровень 3 означает « Impersonation », что означает, и мы цитируем:

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

Короче говоря, наш скрипт (и созданный нами экземпляр службы) «олицетворяют» пользователя с помощью предоставленной учетной записи / пароля. Идеально для того, что нам нужно здесь.

Обратите внимание, что приведенный выше код является способом создания удаленного COM-соединения для управления удаленным ПК. Для управления локальным ПК синтаксис будет немного отличаться, но не сильно:

 <?php $pc = "."; $obj = new COM ("winmgmts:\\\\".$pc."\\root\\cimv2"); $disks = $obj->ExecQuery("Select * from Win32_LogicalDisk"); // Rest of the code is the same as previous remote connection sample 

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

Чтобы получить классы и связанные с ними данные, мы использовали оператор WQL (WMI Query Language). Это очень похоже на операторы SQL, которые мы выдаем серверу MySQL, но в этом случае мы получаем данные из WMI. Win32_LogicalDisk — это одна «таблица» в WMI, в которой хранится вся информация, относящаяся к логическим дискам. Чтобы получить доступ к данным из других таблиц , используйте имя, указанное в диалоговом окне « Query Result », как показано выше. Это также позволяет нам фильтровать результаты. Например, Select * from Win32_LogicalDisk where size > 150000000000 будет возвращать только те логические устройства с размером более Select * from Win32_LogicalDisk where size > 150000000000 (примерно).

Оператор ExecQuery , в случае успеха, вернет объект типизированного variant . Недостатком является то, что если мы попытаемся var_dump этого объекта, PHP просто напечатать что-то вроде object (variant) #3... То же самое происходит, когда мы пытаемся var_dump переменной $d . На самом деле ничего полезного для дальнейшего программирования в выводе нет.

В действительности нам просто нужно знать, что объект является итеративным. В этом случае, когда мы используем цикл foreach , каждый экземпляр $d будет содержать ссылку на объект на логическом диске. Затем мы можем получить доступ к свойствам в этом экземпляре логического диска в знакомой нотации -> . Список свойств можно найти в диалоге Object editor для этого конкретного класса, как показано выше.

Убедитесь, что Win32_LogicalDisk имя класса ( Win32_LogicalDisk ) и имена свойств (например, Size , Name ) правильно. Windows не чувствительна к регистру, но если мы введем неправильное имя, будет выдано сообщение об ошибке и возвращено.

Как мы упоминали ранее, программирование WMI может выполняться и на других языках — таких как C #, VB Script и т. Д. Однако интерфейс WMI COM является таким динамическим интерфейсом, что мы не можем рассчитывать ни на один из этих языков, чтобы обеспечить подсказка завершения кода, чтобы иметь легкий доступ ко всем свойствам. Мы должны полагаться на диалоги, показанные выше.

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

Вывод

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

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

Пожалуйста, оставьте свои комментарии ниже, если вы хотите увидеть более подробное руководство по WMI!