36、Windows 中 WMI 的深入探索与应用

Windows 中 WMI 的深入探索与应用

1. Windows 中 WMI 的基础信息

Windows 在操作系统安装过程中会安装 WMI,其大部分组件,包括存储库、工具和提供程序等,会被安装到 C:\Windows\System32\WBEM 文件夹中。在运行的 Windows 主机里,WMI 以 winmgmt 服务( winmgmt.exe )的形式运行,该服务在共享服务进程( svchost.exe )内执行。早期 Windows 版本的 WMI 会将所有 WMI 提供程序加载到 winmgmt 服务中,单个提供程序的故障可能导致整个 WMI 服务失败。后来,从 Windows XP 及更高版本开始,微软改进了 WMI,将提供程序加载到单独的进程 WmiPrvSE.exe 中。

2. 探索 WBEM 文件夹及相关组件

以下是一系列操作步骤,帮助你深入了解 WMI 的各个方面:
1. 查看 WBEM 文件夹内容

$WBEMFOLDER = "$Env:windir\system32\wbem"
Get-ChildItem -Path $WBEMFOLDER |
  Select-Object -First 20
  1. 查看 WMI 存储库文件夹
Get-ChildItem -Path $WBEMFOLDER\Repository
  1. 查看 WMI 服务详细信息
Get-Service -Name Winmgmt  | 
  Format-List -Property *
  1. 获取进程详细信息
$S = tasklist.exe /svc /fi "SERVICES eq winmgmt" |
       Select-Object -Last 1
$P = [int] ($S.Substring(30,4))
Get-Process -Id $P 
  1. 检查 WMI 服务进程加载的 DLL
Get-Process -Id $P | 
  Select-Object -ExpandProperty modules | 
    Where-Object ModuleName -match 'wmi' |
      Format-Table -Property FileName, Description, FileVersion
  1. 发现 WMI 提供程序
Get-ChildItem -Path $WBEMFOLDER\*.dll | 
  Select-Object -ExpandProperty Versioninfo | 
    Where-Object FileDescription -match 'prov' |
      Format-Table -Property Internalname, 
                             FileDescription, 
                             ProductVersion
  1. 检查 WmiPrvSE 进程
Get-Process -Name WmiPrvSE
  1. 查找 WMI 事件日志
$Log = Get-WinEvent -ListLog *wmi*
$Log
  1. 查看 WMI 日志中的事件类型
$Events = Get-WinEvent -LogName $Log.LogName
$Events | Group-Object -Property LevelDisplayName
  1. 检查 WMI 事件日志条目
$Events |
  Select-Object -First 5 |
    Format-Table -Wrap
  1. 查看 WBEM 文件夹中的可执行程序
$Files = Get-ChildItem -Path $WBEMFOLDER\*.exe
"{0,15}  {1,-40}" -f 'File Name','Description'
Foreach ($File in $Files){
 $Name = $File.Name
 $Desc = ($File | 
          Select-Object -ExpandProperty VersionInfo).FileDescription
"{0,15}  {1,-40}" -f $Name,$Desc
}
  1. 检查 CimCmdlets 模块
Get-Module -Name CimCmdlets |
  Select-Object -ExcludeProperty Exported*
    Format-List -Property *
  1. 查找 CimCmdlets 模块中的 cmdlet
Get-Command -Module CimCmdlets    
  1. 检查 Get-CimInstance 返回的 .NET 类型
Get-CimInstance -ClassName Win32_Share | Get-Member 
3. 探索 WMI 命名空间

WMI 命名空间是组织 CIM 数据库信息的重要方式,PowerShell 的 CIM cmdlet 可用于对其进行操作。以下是相关操作步骤:
1. 查看根命名空间中的 WMI 类

Get-CimClass -Namespace 'ROOT' | 
  Select-Object -First 10
  1. 查看根命名空间中的 __NAMESPACE 类
Get-CimInstance -Namespace 'ROOT' -ClassName __NAMESPACE |
  Sort-Object -Property Name
  1. 获取并统计 ROOT\CIMV2 命名空间中的类
$Classes = Get-CimClass -Namespace 'ROOT\CIMV2'  
"There are $($Classes.Count) classes in ROOT\CIMV2"
  1. 发现 SRV1 上的所有命名空间
Function Get-WMINamespaceEnum {
  [CmdletBinding()]
  Param($NS) 
  Write-Output $NS
  Get-CimInstance "__Namespace" -Namespace $NS @EAHT | 
  ForEach-Object { Get-WMINamespaceEnum "$ns\$($_.name)"   }
}  # End of function
$Namespaces = Get-WMINamespaceEnum 'ROOT' | 
  Sort-Object
"There are $($Namespaces.Count) WMI namespaces on SRV1"
  1. 查看 SRV1 上的前 25 个命名空间
$Namespaces |
  Select-Object -First 25
  1. 创建脚本块以统计命名空间和类
$SB = {
 Function Get-WMINamespaceEnum {
   [CmdletBinding()]
   Param(
     $NS
    ) 
   Write-Output $NS
   $EAHT = @{ErrorAction = 'SilentlyContinue'}
   Get-CimInstance "__Namespace" -Namespace $NS @EAHT | 
     ForEach-Object { Get-WMINamespaceEnum "$NS\$($_.Name)"   }
   }  # End of function
   $Namespaces = Get-WMINamespaceEnum 'ROOT' | Sort-Object
   $WMIClasses = @()
   Foreach ($Namespace in $Namespaces) {
   $WMIClasses += Get-CimClass -Namespace $Namespace
  }
 "There are $($Namespaces.Count) WMI namespaces on $(hostname)"
 "There are $($WMIClasses.Count) classes on $(hostname)"
}
  1. 在 SRV1 上本地运行脚本块
Invoke-Command -ComputerName SRV1 -ScriptBlock $SB
  1. 在 SRV2 上运行脚本块
Invoke-Command -ComputerName SRV2 -ScriptBlock $SB
  1. 在 DC1 上运行脚本块
Invoke-Command -ComputerName DC1 -ScriptBlock $SB
4. 探索 WMI 类

WMI 类定义了 WMI 管理的对象,包含属性、方法和事件等成员。以下是探索 WMI 类的操作步骤:
1. 查看 Win32_Share 类

Get-CimClass -ClassName Win32_Share
  1. 查看 Win32_Share 类的属性
Get-CimClass -ClassName Win32_Share |
  Select-Object -ExpandProperty CimClassProperties |
    Sort-Object -Property Name |
      Format-Table -Property Name, CimType
  1. 获取 Win32_Share 类的方法
Get-CimClass -ClassName Win32_Share |
  Select-Object -ExpandProperty CimClassMethods
  1. 获取非默认命名空间中的类
Get-CimClass -Namespace root\directory\LDAP |
  Where-Object CimClassName -match '^ds_group'
  1. 查看 ds_group 类的实例
Get-CimInstance -Namespace root\directory\LDAP -Classname 'DS_Group' |
  Format-Table -Property DS_name, DS_Member
5. 获取本地和远程 WMI 对象

使用 Get-CimInstance cmdlet 可以获取本地或远程主机上 WMI 类的实例,有以下三种使用方式:
1. 返回所有类的实例和属性 :直接使用 Get-CimInstance 命令,不添加额外参数。
2. 使用 -Filter 参数指定 WMI 过滤器 :例如 Get-CimInstance -ClassName <类名> -Filter "<过滤条件>"
3. 使用 WMI 查询语言(WQL) :例如 Get-CimInstance -Query "SELECT * FROM <类名> WHERE <条件>"

当通过网络使用 WMI 时,指定过滤器或完整的 WMI 查询可以减少网络传输的数据量,提高性能。

总结

通过以上步骤,你可以全面深入地了解 Windows 中 WMI 的各个方面,包括 WBEM 文件夹内容、WMI 命名空间、WMI 类以及如何获取本地和远程 WMI 对象。这些操作对于系统管理和故障排除都具有重要意义。

流程图

graph LR
    A[开始] --> B[探索 WBEM 文件夹]
    B --> C[探索 WMI 命名空间]
    C --> D[探索 WMI 类]
    D --> E[获取本地和远程 WMI 对象]
    E --> F[结束]

表格

操作步骤 相关命令
查看 WBEM 文件夹内容 Get-ChildItem -Path $WBEMFOLDER | Select-Object -First 20
查看 WMI 存储库文件夹 Get-ChildItem -Path $WBEMFOLDER\Repository
查看 WMI 服务详细信息 Get-Service -Name Winmgmt | Format-List -Property *
获取进程详细信息 $S = tasklist.exe /svc /fi "SERVICES eq winmgmt" | Select-Object -Last 1; $P = [int] ($S.Substring(30,4)); Get-Process -Id $P
检查 WMI 服务进程加载的 DLL Get-Process -Id $P | Select-Object -ExpandProperty modules | Where-Object ModuleName -match 'wmi' | Format-Table -Property FileName, Description, FileVersion
发现 WMI 提供程序 Get-ChildItem -Path $WBEMFOLDER\*.dll | Select-Object -ExpandProperty Versioninfo | Where-Object FileDescription -match 'prov' | Format-Table -Property Internalname, FileDescription, ProductVersion
检查 WmiPrvSE 进程 Get-Process -Name WmiPrvSE
查找 WMI 事件日志 $Log = Get-WinEvent -ListLog *wmi*; $Log
查看 WMI 日志中的事件类型 $Events = Get-WinEvent -LogName $Log.LogName; $Events | Group-Object -Property LevelDisplayName
检查 WMI 事件日志条目 $Events | Select-Object -First 5 | Format-Table -Wrap
查看 WBEM 文件夹中的可执行程序 $Files = Get-ChildItem -Path $WBEMFOLDER\*.exe; "{0,15} {1,-40}" -f 'File Name','Description'; Foreach ($File in $Files){ $Name = $File.Name; $Desc = ($File | Select-Object -ExpandProperty VersionInfo).FileDescription; "{0,15} {1,-40}" -f $Name,$Desc }
检查 CimCmdlets 模块 Get-Module -Name CimCmdlets | Select-Object -ExcludeProperty Exported*; Format-List -Property *
查找 CimCmdlets 模块中的 cmdlet Get-Command -Module CimCmdlets
检查 Get-CimInstance 返回的 .NET 类型 Get-CimInstance -ClassName Win32_Share | Get-Member
查看根命名空间中的 WMI 类 Get-CimClass -Namespace 'ROOT' | Select-Object -First 10
查看根命名空间中的 __NAMESPACE 类 Get-CimInstance -Namespace 'ROOT' -ClassName __NAMESPACE | Sort-Object -Property Name
获取并统计 ROOT\CIMV2 命名空间中的类 $Classes = Get-CimClass -Namespace 'ROOT\CIMV2'; "There are $($Classes.Count) classes in ROOT\CIMV2"
发现 SRV1 上的所有命名空间 Function Get-WMINamespaceEnum { [CmdletBinding()]; Param($NS); Write-Output $NS; Get-CimInstance "__Namespace" -Namespace $NS @EAHT | ForEach-Object { Get-WMINamespaceEnum "$ns\$($_.name)" } }; $Namespaces = Get-WMINamespaceEnum 'ROOT' | Sort-Object; "There are $($Namespaces.Count) WMI namespaces on SRV1"
查看 SRV1 上的前 25 个命名空间 $Namespaces | Select-Object -First 25
创建脚本块以统计命名空间和类 $SB = { Function Get-WMINamespaceEnum { [CmdletBinding()]; Param($NS); Write-Output $NS; $EAHT = @{ErrorAction = 'SilentlyContinue'}; Get-CimInstance "__Namespace" -Namespace $NS @EAHT | ForEach-Object { Get-WMINamespaceEnum "$NS\$($_.Name)" } }; $Namespaces = Get-WMINamespaceEnum 'ROOT' | Sort-Object; $WMIClasses = @(); Foreach ($Namespace in $Namespaces) { $WMIClasses += Get-CimClass -Namespace $Namespace }; "There are $($Namespaces.Count) WMI namespaces on $(hostname)"; "There are $($WMIClasses.Count) classes on $(hostname)" }
在 SRV1 上本地运行脚本块 Invoke-Command -ComputerName SRV1 -ScriptBlock $SB
在 SRV2 上运行脚本块 Invoke-Command -ComputerName SRV2 -ScriptBlock $SB
在 DC1 上运行脚本块 Invoke-Command -ComputerName DC1 -ScriptBlock $SB
查看 Win32_Share 类 Get-CimClass -ClassName Win32_Share
查看 Win32_Share 类的属性 Get-CimClass -ClassName Win32_Share | Select-Object -ExpandProperty CimClassProperties | Sort-Object -Property Name | Format-Table -Property Name, CimType
获取 Win32_Share 类的方法 Get-CimClass -ClassName Win32_Share | Select-Object -ExpandProperty CimClassMethods
获取非默认命名空间中的类 Get-CimClass -Namespace root\directory\LDAP | Where-Object CimClassName -match '^ds_group'
查看 ds_group 类的实例 Get-CimInstance -Namespace root\directory\LDAP -Classname 'DS_Group' | Format-Table -Property DS_name, DS_Member

Windows 中 WMI 的深入探索与应用

6. 操作注意事项与分析

在前面的操作中,有一些细节值得进一步分析:
- WBEM 文件夹操作 :在查看 WBEM 文件夹内容时,只显示了前 20 个文件/文件夹,实际上该文件夹包含更多文件,其中就有系统可用的 WMI 提供程序的 DLL 文件。
- WmiPrvSE 进程 :查看 WmiPrvSE 进程时,该进程用于托管 WMI 提供程序。根据 WMI 当前的操作,主机上可能会出现零个、一个或多个该进程实例。
- WMI 系统事件日志 :在查看 WMI 系统事件日志时,在 SRV1 上可以看到既有错误(Error)也有信息(Information)类型的日志条目。信息条目大多表明 WMI 已加载并调用了特定的提供程序。大多数情况下,看到的错误事件消息是暂时的或无害的。
- Get-CimInstance 返回数据 :查看 Get-CimInstance 返回的数据时,该 cmdlet 返回从 WMI 类获取的数据,这些数据封装在一个 .NET 对象中,类名为 Microsoft.Management.Infrastructure.CimInstance ,并带有一个后缀表示 WMI 类的路径。返回的对象及其内容与 Get-WMIObject 返回的不同,这在升级以前使用旧 WMI cmdlet 的 Windows PowerShell 脚本时可能会成为问题。

7. 重要命名空间分析

WMI 中有许多命名空间和类,不同的命名空间和类有不同的用途:
| 命名空间 | 说明 |
| ---- | ---- |
| ROOT\CIMV2 | 由 Win32 WMI 提供程序实现,包含对 IT 专业人员有用的 WMI 类,这些类提供了系统软件和硬件的详细信息,如 BIOS、操作系统、文件等。 |
| ROOT\directory\LDAP | 不太常用的命名空间,包含与 Active Directory 相关的类。虽然大部分 AD 管理使用 AD cmdlet,但该命名空间的某些功能(如事件处理)是 AD cmdlet 所没有的,可能会很有用。 |

8. 常见问题及解决思路
  • 脚本升级问题 :由于 Get-CimInstance 返回的数据与 Get-WMIObject 不同,在升级 Windows PowerShell 脚本时,需要注意对返回对象的处理。可以通过详细测试新脚本,确保其能正确处理新的数据格式。
  • WMI 错误事件处理 :对于 WMI 系统事件日志中的错误事件,大多数是暂时的或无害的。但如果错误事件频繁出现,需要进一步分析具体的错误信息,查看是否是某个 WMI 提供程序出现问题,或者是系统配置存在异常。
9. 总结与建议

通过对 Windows 中 WMI 的全面探索,我们了解了其安装位置、服务运行方式、命名空间、类以及如何获取本地和远程对象等内容。以下是一些总结和建议:
- 操作总结
- 可以使用一系列 PowerShell 命令来查看 WBEM 文件夹、WMI 服务、命名空间、类等信息。
- 利用 Get-CimInstance cmdlet 可以方便地获取本地或远程主机上 WMI 类的实例,并且可以通过不同的方式指定过滤条件,减少网络传输数据量。
- 建议
- 在进行 WMI 相关操作时,尤其是涉及到系统配置和远程操作,建议先在测试环境中进行测试,避免对生产环境造成影响。
- 对于复杂的 WMI 查询和操作,可以编写脚本进行自动化处理,提高工作效率。

流程图

graph LR
    A[开始] --> B[分析 WBEM 文件夹操作]
    B --> C[分析 WmiPrvSE 进程]
    C --> D[分析 WMI 系统事件日志]
    D --> E[分析 Get-CimInstance 返回数据]
    E --> F[分析重要命名空间]
    F --> G[解决常见问题]
    G --> H[总结与建议]
    H --> I[结束]

表格

问题类型 问题描述 解决思路
脚本升级问题 Get-CimInstance 返回数据与 Get-WMIObject 不同,升级脚本可能出现问题 详细测试新脚本,确保能正确处理新的数据格式
WMI 错误事件处理 WMI 系统事件日志中错误事件频繁出现 进一步分析具体错误信息,查看是否是 WMI 提供程序或系统配置问题
【直流微电网】径向直流微电网的状态空间建模线性化:一种耦合DC-DC变换器状态空间平均模型的方法 (Matlab代码实现)内容概要:本文介绍了径向直流微电网的状态空间建模线性化方法,重点提出了一种基于耦合DC-DC变换器状态空间平均模型的建模策略。该方法通过对系统中多个相互耦合的DC-DC变换器进行统一建模,构建出整个微电网的集中状态空间模型,并在此基础上实施线性化处理,便于后续的小信号分析稳定性研究。文中详细阐述了建模过程中的关键步骤,包括电路拓扑分析、状态变量选取、平均化处理以及雅可比矩阵的推导,最终通过Matlab代码实现模型仿真验证,展示了该方法在动态响应分析和控制器设计中的有效性。; 适合人群:具备电力电子、自动控制理论基础,熟悉Matlab/Simulink仿真工具,从事微电网、新能源系统建模控制研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握直流微电网中多变换器系统的统一建模方法;②理解状态空间平均法在非线性电力电子系统中的应用;③实现系统线性化并用于稳定性分析控制器设计;④通过Matlab代码复现和扩展模型,服务于科研仿真教学实践。; 阅读建议:建议读者结合Matlab代码逐步理解建模流程,重点关注状态变量的选择平均化处理的数学推导,同时可尝试修改系统参数或拓扑结构以加深对模型通用性和适应性的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值