郭建伟
在对系统进行管理维护时,我们需要深入了解系统的软件硬件配置信息,在此基础上才能对系统进行灵活的配置。实际上,利用系统内置的功能强大的PowerShell组件,就可以让用户轻而易举地洞察并收集详细的系统信息。更重要的是,利用PowerShell提供的检测命令,还可以让您获取使用常规方式无法得到的各种信息。
PowerShell的WMI调用机制
在PowerShell中内置了WMI调用机制,可以帮助用户了解到很多系统信息。对于一个计算机系统来说,基本上包括软件和硬件两个部分。硬件包括了 CPU、内存、磁盘、网卡、显卡等,而软件包括操作系统以及各种应用程序,這些软硬件分别来自不同的厂商。而DMTF(Distributed Management Task Force,台式系统任务管理组)是一个国际化标准组织,其制定了一个通用的获取不同组件的模型和方法,叫作 CIM(Common Information Model,通用信息模型)。标准制定好之后,各个组件的厂商在发布他们产品的时候,都会向操作系统提供一组相关的 CIM 类,通过这些 CIM 类,应用程序就可以轻松地获取各种组件的信息。而 CIM 标准在 Windows 平台就是利用WMI(Windows Management Instrumentation,Windows管理规范)机制实现的。也就是说通过 WMI,用户就可以获取系统中不同组件的信息。在Windows中,利用PowerShell命令,就可以借助于WMI调用来查看各种软硬件信息。
查看WMI组件信息
WMI是一个通用信息的模型,该模型存在一个Root根节点,在其下有数量众多功能各异的WMI Provider,不同的Provider(提供者)可以帮助用户获取对应组件的信息。随着Windows版本的演化,WMI的类库也变得极为丰富。对于PowerShell来说,可以通过“Get-WmiObject”入口,来访问非常完善的信息库。当然,在使用PowerShell调用WMI来获取所需的系统信息时(例如CPU的类型等),必须首先了解需要使用到的WMI中的具体的类才行。在Windows中存在WMI的类库,该类库会由WMI服务管理和维护。
当访问WMI类库中的类时,就会利用RPC/DCOM协议与该服务进行通讯。例如在Windows 10中点击“Win+R”键,执行执行“wmimgmt.msc”命令,在打开窗口(图1)中左侧的“WMI控件(本地)”节点的右键菜单上点击“属性”项,就会和本地的WMI服务建立连接,在属性窗口中的“常规”面板中显示WMI的版本和类库位置信息,其默认位置为“C:\Windows\System32\wbem”。
在“安全”面板(图2)中打开“Root”节点,会显示WMI的命名空间信息。在其中显示了不同的命令空间节点,分别包含着对应的WMI类。这就意味着,我们要调用 WMI 类,必须指定正确的命令空间。这就像我们打开文件一样,只有打开正确的路径后,才能够正常访问文件。当使用PowerShell来访问WMI的类库,获取相关的系统信息时,必须指定对应的入口,这就和上述不同的命令空间相对应。在“高级”面板(图3)中显示脚本程序默认的命令空间为“root\cimv2”,您可以点击“更改”按钮,在打开的窗口(图4)中选择所需的命令空间,点击确定按钮,将其指定为默认的命令空间。
使用PowerShell命令,检测信息系统
实际上,当点击打开不同的命名空间路径后,会发现看不到具体的类,为此可以通过 Powershell 的方法来获取具体命令空间下的所有类。例如执行“Get-WmiObject -Namespace root\cimv2 -ClassName Win32_OperatingSystem”命令,显示常规的操作系统信息(图5)。其中的“root\cimv2”就是一个命令空间项目,但是在上述“安全”面板中打开“Root”→“CIMV2”分支,却看不到所需的WMI类。其实只需执行“Get-WmiObject -List -Namespace root\cimv2”命令,就会显示该命令空间名称下的所有的WMI类信息(图6)。
执行“Get-WmiObject -List -Namespace root\cimv2 | measure”命令,会显示这些类的数量。因为涉及到类的数量很多,利用PowerShell的筛选功能,可以只显示指定的类。执行“Get-Wmiobject -List -Namespace root\cimv2 | where {$_.name -like "*memory*" }”命令,会在其中过滤和内存相关的类的信息。执行“Get-Wmiobject Win32_PhysicalMemory”命令,会显示详细的内存配置信息(图7)。注意,其效果与执行“Get-WmiObject -Namespace root\cimv2 -ClassName Win32_PhysicalMemory”命令是等效的。
打开上述属性窗口的“高级”面板,在“脚本程序的默认命令空间”栏中显示“root\cimv2”,所以即使不指定命令空间名称,PowerShell也会使用默认的名称。执行“Get-Wmiobject Win32_Processor”命令,会显示CPU的基本信息。执行“Get-Wmiobject Win32_Processor | fl *”命令,会显示该CPU的详细信息。执行“Get-WmiObject -Class Win32_Logicaldisk”命令,显示基本磁盘信息。
也可以执行“Get-WmiObject -Class Win32_Logicaldisk | where {$_.DriveType -eq 3}”等命令,来筛选指定类型的磁盘信息。执行“Get-WmiObject -Class Win32_PhysicalMemory | Select-Object Manufacturer,SerialNumber,Capacity”命令,可以显示指定的内存信息,例如内存厂商名称、串号、总容量等。执行“Get-CimInstance -Namespace Root\StandardCIMv2 -ClassName MSFT_Netadapter”命令,可以获取详细的网卡信息。
执行“Get-WmiObject -Query "select * from Win32_LogicalDisk Where DriveType=3" | fl *”命令,来显示硬盘信息(图8)。如果将其中的“DriveType”的值修改为0、2、4、5、6,可以显示未知、移动存储、共享盘、光盘、内存盘等磁盘信息。也可以执行“Get-WmiObject -Query "select * from Win32_LogicalDisk Where DriveType=3" | Select-Object @{n="盘符";e={$_.name},@{n="自由空间";e={$_.freespace}/1GB -as [int] }”命令,来自定义显示的磁盘信息。
如果想查看目标主机的常用信息,例如名称、运行时间等,可以执行“Get-WmiObject -Class Win32_OperatingSystem -ComputerName server1.xxx.com | Select-Object @{n='计算机名称';e={$_.PSComputername}},@{n="安装时间";e={$_.ConvertToDateTime($_.InstallDate)}},@{n="启动时间";e={$_.ConvertToDateTime($_.LastBootUpTime)}},@{n="系统版本";e={$_.Caption}}”命令,来获取相关的信息(图9)。注意,这里使用的“ConvertToDateTime”是PowerShell提供的方法,并非是WMI类内部提供的。其中的“server1.xxx.com”为目标主机的名称,如果省略该值,表示针对当前主机进行操作。
使用PowerShell命令,配置系统信息
对于WMI的类来说,不仅可以帮助用户查看系统信息,利用其提供的接口还可以对系统的配置进行相应的调整。這里就以设置远程桌面服务为例进行说明。例如执行“Get-WmiObject -List -Namespace root\cimv2\terminalServices”命令,来查看和远程桌面相关的类,在返回信息中会显示名为“Win32_TerminalServiceSetting”的类,利用该类可对远程桌面组件的配置进行修改。执行“Get-WmiObject -Namespace root\cimv2\terminalservices -Class Win32_TerminalServiceSetting | Get-Member | where {$_.MemberType} -eq "Method"”命令,显示该类中所有的方法信息。
执行“Get-WmiObject -Namespace root\cimv2\terminalservices -Class Win32_TerminalServiceSetting -ComputerName server1.xxx.com |ft servername,AllowTSConnections”命令,会显示指定的目标主机是否开启了远程桌面服务,如果显示为0表示没有启用,为1表示已经启用。如果该机没有启用远程桌面功能,可以执行“$RDP = Get-WmiObject -Namespace ROOT\CIMV2\TerminalServices -Class Win32_TerminalServiceSetting -ComputerName server1.xxx.com”命令,定义一个变量,来获取目标主机的WMI接口。
执行“$RDP.SetAllowTSConnections(1,1)”命令,利用该接口来执行“SetAllowTSConnections”方法,其中的第一个参数“1”表示开启远程桌面,第二个参数“1”允许在防火墙上开放远程桌面使用网络端口。执行“Test-NetConnection -ComputerName server1.xxx.com -CommonTCPPort RDP”命令,进行连接测试操作,在返回信息的“TcpTestSucceeded”栏中显示“Ture”,表示可以顺利连接到该机的远程桌面。