PHP 和 WMI – 使用 PHP 深入研究 Windows

有许多运行 Windows 操作系统的设备(服务器、台式机、笔记本电脑、平板电脑、电话等)。我们中的许多生活在基于 nix 的世界中的人都必须在这个操作系统中工作,或者如果我们不这样做,我们迟早会这样做。除了我们可以从 *nix 系统中获得的常规工具(比如 Apache、PHP、MySQL、C/C++ 编译器等)之外,Windows 还提供了一组其他操作系统中不存在的独特功能,WMI 就是其中之一。

在本文中,我们将解决以下问题:什么是 WMI?如何在 PHP 中使用 WMI?我们将有一些最小的示例代码来了解基本的编程技术。

什么是 WMI 以及为什么我们需要处理它

MSDN网站在这篇文章中有它对WMI的官方定义,其中摘录几行如下:

Windows Management Instrumentation (WMI) 是 Microsoft 实施的基于 Web 的企业管理 (WBEM),它是一项行业倡议,旨在开发用于在企业环境中访问管理信息的标准技术。

这里的三个关键词是:Web-Based管理信息企业环境。因此,如果我们的托管 IT 环境是一个大规模的基于 Windows 的体系结构,并且我们想要检索每个单独节点的管理信息并以 Web 方式呈现它,我们将需要与 WMI 交互。WMI 还能够执行其他操作,例如在远程 PC 中生成进程,但这超出了本文的范围。

WMI 提供机器的全面知识,包括硬件和软件。它具有所谓的 CIM(通用信息模型)以面向对象的方式封装信息。它还提供了几个编程接口来检索所述信息。在纯 Windows 环境中,这些将是PowerShell、VB 脚本和 .NET 语言。但在我们的例子中,它将是 PHP。

使用 WMI 编程时的基本问题之一是:哪些“信息”可用?换句话说,哪些对象/类可用?幸运的是,Microsoft 提供了 WMI 在类及其属性方面提供的完整列表。请访问此处获取完整参考。在 WMI 编程中,大多数时候我们指的是Win32 类

先决条件

在主机 Windows 机器上,必须安装 WMI 以提供 CIM。默认情况下,任何比 Windows XP 更新的 Windows 系统都应该安装并启用 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”)前加上我们需要连接的 PC 的 IP 或名称(“\\192.168.1.2\root\cimv2例如”),并提供该远程机器的用户名和密码。

WMI (.NET) 的 PHP 扩展

要在 PHP 中使用 WMI(或更准确地说,.NET 功能),我们需要启用php_com_dotnet.dll. 像这样添加一行php.ini

extension=php_com_dotnet.dll

并重新启动 Web 服务器。

注意: php_com_dotnet.dll是一个仅限 Windows 的扩展。这意味着我们必须在类似 WAMP 的环境中运行调用 WMI 的 PHP 文件,而不是在 *nix 环境中。当然,我们将通过 WMI 管理的机器都需要基于 Windows。

进一步了解 WMI 提供的功能

完成所有必要的准备工作之后,在我们开始使用 PHP 编写 WMI 之前,我们真的需要回到我们之前提出的基本问题:有哪些“信息”可用?

我们可以期望 WMI 提供有关 BIOS、CPU、磁盘、内存使用等的信息。但是这些信息是如何呈现的呢?

除了深入研究提供的官方文档之外,让我们wbemtest再次打开对话框并连接到我们的本地机器。在WMI Tester对话框中,单击Enum Classes...按钮并弹出以下对话框:

在此对话框中,不要在文本框中输入任何内容,选择Recursive并单击OK。它应该会弹出另一个对话框,如下所示:

这是一个很长的列表(我的 Windows 8.1 PC 中有 1,110 个对象)。您的 PC 可能会给出不同的列表,但应该与此列表大致相同。请花一些时间滚动浏览它并查看 WMI 提供的类的名称。例如,在上图中,我们突出显示了一个类Win32_LogicalDisk。这包含与机器的逻辑磁盘相关的所有信息。要更深入地了解该课程提供的内容,请双击该课程,然后Object editor会出现另一个对话框:

仔细查看“属性”面板。这里列出的所有属性都是我们可以检索的。例如,VolumeName将是我们为逻辑磁盘分配的名称。

WMI 的 Win32 类有很多条目可供查看。一些最常用的是:

  • 计算机系统硬件类,包括散热设备、输入设备(键盘、鼠标等)、大容量存储、主板、网络设备、打印、视频和显示器等。
  • 已安装的应用程序类,包括字体等。
  • 操作系统类,包括驱动程序、内存、进程、注册表、用户等。
  • 性能计数器类,包括所有与性能相关的类。
  • 等等等等

我们现在对 WMI 类的结构及其相关属性有了更清晰的了解。

用 PHP 编写 WMI

下面的代码片段显示了 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方法建立与 PC 的连接。此方法调用的四个参数是不言自明的。最后,我们需要将安全模拟设置为适当的级别。级别 3 是 WMI 脚本的推荐级别。此处记录了该级别的详细说明。第 3 级表示“ Impersonation”,这意味着我们引用:

服务器进程可以在其本地系统上模拟客户端的安全上下文。服务器无法在远程系统上模拟客户端。

简而言之,我们的脚本(以及我们创建的服务实例)正在使用提供的帐户/密码“模拟”用户。非常适合我们在这里需要的东西。

请注意,上面的代码是创建远程 COM 连接以管理远程 PC 的方法。要管理本地 PC,语法会略有不同,但差别不大:

<?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 查询语言)语句。它与我们向 MySQL 服务器发出的 SQL 语句非常相似,但在这种情况下,我们从 WMI 检索数据。Win32_LogicalDisk是 WMI 中的一个“表”,用于存储与逻辑磁盘相关的所有信息。要访问其他Query Result中的数据,请使用如上所示对话框中列出的名称。这也允许我们过滤结果。例如,Select * from Win32_LogicalDisk where size > 150000000000只会返回那些大小超过 150G(大约)的逻辑设备。

ExecQuery如果成功,该语句将返回一个variant类型化的对象。一个缺点是,如果我们尝试使用var_dump该对象,PHP 将简单地打印类似object (variant) #3...var_dump当我们尝试使用$d变量时,也会发生同样的事情。实际上对于输出中的进一步编程没有任何用处。

实际上,我们只需要知道对象是可迭代的。在这种情况下,当我们使用foreach循环时,每个$d实例都会持有一个对逻辑磁盘的对象引用。->然后我们可以使用熟悉的符号访问该逻辑磁盘实例中的属性。属性列表可以在Object editor该特定类的对话框中找到,如上所示。

请务必正确拼写类名 ( Win32_LogicalDisk) 和属性名(如SizeName)。Windows 不区分大小写,但如果我们提供错误的名称,则会引发并返回错误。

正如我们前面提到的,WMI 编程也可以用其他语言来完成——像 C#、VB Script 等语言。但是,WMI COM 接口是一个动态接口,我们不能指望这些语言中的任何一种提供代码完成提示可以轻松访问所有属性。我们必须依赖上面显示的对话。

帮助程序员的一种解决方案是进一步将每个 WMI 类封装成一个带有必要方法的 PHP 类。这应该是一项非常简单的任务,我将把它留给有兴趣的人来玩。

结论

WMI 是一个强大的工具,它包含一些由 Windows 操作系统保存的最隐秘的秘密。在具有同构基于 Windows 的机器的大规模网络中,我们可以依靠 WMI 来检索这些重要信息并帮助系统管理员更好地管理所有机器。

在本文中,我们仅介绍 WMI 和 PHP WMI 编程的基础知识,但为进一步的工作奠定了基础。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值