[TOC]
0x00 前言简述
Q: 什么是WMI? 答: WMI出现至今已经多年,但很多人对它并不熟悉。知道它很好很强大,但不知道它从哪里来,怎么工作,使用范围是什么?
WMI有一组API我们不管使用VBScript、PowerShell脚本还是利用C#的来访问WMI的类库,都是因为WMI向外暴露的一组API。这些API是在系统安装WMI模块的时候安装的,通过他们我们能够能拿到我们想要的类。 WMI有一个存储库。尽管WMI的多数实例数据都不存储在WMI中,但是WMI确实有一个存储库,用来存放提供程序提供的类信息,或者称为类的蓝图或者Schema。 WMI有一个Service。WMI总是能够响应用户的访问,那是因为它有一个一直运行的Windows服务,名字叫Winmgmt。停止这个服务,所有对WMI的操作都将没有反应。 WMI是可扩展的。人人都知道WMI能干很多事情,读取本机硬盘信息、读取远程计算机的用户信息、读取域用户信息等等。基本上你能想到的获取或者更改资源的操作它都能干。可谓吃得少干得多。它为什么这么能干呢?这基于WMI的可扩展性。WMI对资源的操作,不是它自己实现了什么方法,而完全取决于向它注册的提供程序。 WMI是管理员日常必备的强大工具之一,是脚本伴侣。当然也可以把一个大型系统建立在WMI以及WMI的提供程序之上
Q: WMI 可以做什么? 答: 通过使你的驱动程序成为 WMI 提供程序,你可以:
- 使自定义数据可用于 WMI 使用者。
- 允许 WMI 使用者通过标准接口而不是自定义控制面板应用程序来配置设备。
- 通知驱动程序定义事件的 WMI 使用者,无需使用者轮询或发送 Irp。
- 通过只收集请求的数据并将其发送到单个目标来减少驱动程序开销。
- 用描述性驱动程序定义的类名和可选说明注释数据和事件块,然后 WMI 客户端可以枚举并显示给用户。
Q: WMI 管理的常用命令以及工具
- wmic.exe - Cmd 命令
- Get-CimClass - Powershell 命令
- Get-CimInstance - Powershell 命令
- Get-WmiObject - Powershell 命令
0x01 命令解析
1.Get-CimClass 命令 - 获取特定命名空间中CIM类的列表
语法参数:
代码语言:javascript复制Get-CimClass [[-ClassName] <System.String>] [[-Namespace] <System.String>] -CimSession <Microsoft.Management.Infrastructure.CimSession[]> [-MethodName <System.String>] [-OperationTimeoutSec <System.UInt32>] [-PropertyName <System.String>] [-QualifierName <System.String>] [<CommonParameters>]
Get-CimClass [[-ClassName] <System.String>] [[-Namespace] <System.String>] [-ComputerName <System.String[]>] [-MethodName <System.String>] [-OperationTimeoutSec <System.UInt32>] [-PropertyName <System.String>] [-QualifierName <System.String>] [<CommonParameters>]
基础示例:
代码语言:javascript复制# - 1.获取所有类定义以及条数
Get-CimClass ; (Get-CimClass).count
# NameSpace:ROOT/CIMV2
# Win32_DeviceChangeEvent {} {SECURITY_DESCRIPTOR, TIME_CREATED, EventType}
# Win32_SystemConfigurationChangeE... {} {SECURITY_DESCRIPTOR, TIME_CREATED, EventType}
# Win32_VolumeChangeEvent {} {SECURITY_DESCRIPTOR, TIME_CREATED, EventType, DriveName}
# MSFT_WMI_GenericNonCOMEvent {} {SECURITY_DESCRIPTOR, TIME_CREATED, ProcessId, PropertyName...
# MSFT_NCProvEvent {} {SECURITY_DESCRIPTOR, TIME_CREATED, Namespace, ProviderName...
# 1234
# - 2.获取具有特定名称的类以及获取具有特定方法名称、属性、限定符名称、名称空间的类
Get-CimClass -ClassName *disk*
# CimClassName CimClassMethods CimClassProperties
# ------------ --------------- ------------------
# CIM_DiskDrive {SetPowerState, R... {Caption, Description, InstallDate, Name...}
# Win32_DiskDrive {SetPowerState, R... {Caption, Description, InstallDate, Name...
Get-CimClass -ClassName Win32* -MethodName Term*
Get-CimClass -ClassName Win32* -PropertyName Handle
Get-CimClass -ClassName Win32*Disk* -QualifierName Association
# - 获取WMI类并进行排序
Get-CimClass -Namespace root/CIMV2 |
Where-Object CimClassName -like Win32* |
Select-Object CimClassName
# - 3.从远程服务器获取类定义以及使用CIM会话获取类
$s = New-CimSession -ComputerName Server01, Server02
Get-CimClass -ClassName *disk* -CimSession $s
# 或者
Get-CimClass -ClassName *disk* -ComputerName Server01, Server02
2.Get-CimInstance - 从CIM服务器获取类的CIM实例
基础语法:
代码语言:javascript复制Get-CimInstance -CimSession <Microsoft.Management.Infrastructure.CimSession[]> [-Filter <System.String>] [-KeyOnly] [-Namespace <System.String>] [-OperationTimeoutSec <System.UInt32>] [-Property <System.String[]>] [-ResourceUri <System.Uri>] [-Shallow] [<CommonParameters>]
Get-CimInstance -CimSession <Microsoft.Management.Infrastructure.CimSession[]> [-Namespace <System.String>] [-OperationTimeoutSec <System.UInt32>] -Query <System.String> [-QueryDialect <System.String>] [-ResourceUri <System.Uri>] [-Shallow] [<CommonParameters>]
Get-CimInstance [-ClassName] <System.String> -CimSession <Microsoft.Management.Infrastructure.CimSession[]> [-Filter <System.String>] [-KeyOnly] [-Namespace <System.String>] [-OperationTimeoutSec <System.UInt32>] [-Property <System.String[]>] [-QueryDialect <System.
String>] [-Shallow] [<CommonParameters>]
Get-CimInstance [-InputObject] <Microsoft.Management.Infrastructure.CimInstance> -CimSession <Microsoft.Management.Infrastructure.CimSession[]> [-OperationTimeoutSec <System.UInt32>] [-ResourceUri <System.Uri>] [<CommonParameters>]
Get-CimInstance [-ClassName] <System.String> [-ComputerName <System.String[]>] [-Filter <System.String>] [-KeyOnly] [-Namespace <System.String>] [-OperationTimeoutSec <System.UInt32>] [-Property <System.String[]>] [-QueryDialect <System.String>] [-Shallow] [<CommonParameters>]
Get-CimInstance [-InputObject] <Microsoft.Management.Infrastructure.CimInstance> [-ComputerName <System.String[]>] [-OperationTimeoutSec <System.UInt32>] [-ResourceUri <System.Uri>] [<CommonParameters>]
Get-CimInstance [-ComputerName <System.String[]>] [-Filter <System.String>] [-KeyOnly] [-Namespace <System.String>] [-OperationTimeoutSec <System.UInt32>] [-Property <System.String[]>] [-ResourceUri <System.Uri>] [-Shallow] [<CommonParameters>]
Get-CimInstance [-ComputerName <System.String[]>] [-Namespace <System.String>] [-OperationTimeoutSec <System.UInt32>] -Query <System.String> [-QueryDialect <System.String>] [-ResourceUri <System.Uri>] [-Shallow] [<CommonParameters>]
基础示例:
代码语言:javascript复制# - 1.获取指定类的CIM实例
Get-CimInstance -ClassName Win32_Process
# ProcessId Name HandleCount WorkingSetSize VirtualSize
# --------- ---- ----------- -------------- -----------
# 0 System Idle Process 0 8192 8192
# 4 System 6692 32768 3985408
Get-CimInstance Win32_ComputerSystemProduct # 获取计算机硬件信息
# IdentifyingNumber : 8QVY862
# Name : OptiPlex 9020
# Vendor : Dell Inc.
# Version : 01
# Caption : 计算机系统产品
# 指定类名与命名空间格式化输出选取前十行
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Process|format-table processid,name,executablepath |Select-Object -First 10
# - 2.从WMI服务器获取名称空间列表
Get-CimInstance -Namespace root -ClassName __Namespace
# Name PSComputerName
# ---- --------------
# subscription
# DEFAULT
# CIMV2
# msdtc
# Cli
# SECURITY
# SecurityCenter2
# RSOP
# PEH
# StandardCimv2
# WMI
# IntelNCS2
# directory
# Policy
# Interop
# Hardware
# ServiceModel
# SecurityCenter
# Microsoft
# Appv
# - 3.获取使用查询筛选的类的实例
Get-CimInstance -Query "SELECT * from Win32_Process WHERE name LIKE 'P%'"
# ProcessId Name HandleCount WorkingSetSize VirtualSize
# --------- ---- ----------- -------------- -----------
# 2816 PresentationFontCache.exe 242 1204224 4868018176
# 28800 powershell.exe 870 101203968 2204067848192
# - 4.获取通过使用类名和筛选器表达式筛选的类的实例
Get-CimInstance -ClassName Win32_Process -Filter "Name like 'P%'"
Get-CimInstance -Class Win32_Process -Namespace ROOTCIMV2 -Filter "name = 'qq.exe'"|format-table processid,name,executablepath
# - 5.获取只填写了键属性的CIM实例
$x = New-CimInstance -ClassName Win32_Process -Namespace rootcimv2 -Property @{ "Handle"=0 } -Key Handle -ClientOnly
Get-CimInstance -CimInstance $x
# ProcessId Name HandleCount WorkingSetSize VirtualSize
# --------- ---- ----------- -------------- -----------
# 0 System Idle Process 0 8192 8192
# 只获取键属性而不是所有属性
$x = Get-CimInstance -Class Win32_Process -KeyOnly
$x | Invoke-CimMethod -MethodName GetOwner
# 仅获取属性的子集,而不是所有属性
# 使用属性参数检索的实例可用于执行其他CIM操作,例如“Set CimInstance”或“Invoke CimMethod”。
$x = Get-CimInstance -Class Win32_Process -Property Name,KernelModeTime
$x | Invoke-CimMethod -MethodName GetOwner
# - 6.检索CIM实例并重用它们
$x,$y = Get-CimInstance -ClassName Win32_Process
$x | Format-Table -Property Name,KernelModeTime -AutoSize
# Name KernelModeTime
# ---- --------------
# System Idle Process 57588234843750
# - 7.从远程计算机获取CIM实例
Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName Server01,Server02
# using CIM session
$s = New-CimSession -ComputerName Server01,Server02
Get-CimInstance -ClassName Win32_ComputerSystem -CimSession $s
# - 8.创建与删除进程
# Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Process -Path "'C:WindowsSystem32cmd.exe'" | Invoke-CimMethod -Name create
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Process -Filter "name = 'qq.exe'" | Invoke-CimMethod -Name Terminate
# - 9.查詢服务信息以及开启/关闭服务
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Service -Filter "State='Running'" # 获取正在运行的服务列表
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Service -Filter "name='spooler'"|Invoke-CimMethod -Name startservice # 开启打印后台处理程序
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Service -Filter "name='spooler'"|Invoke-CimMethod -Name stopservice # 关闭打印后台处理程序
# - 10.查看安装的软件信息
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Product |format-table name,version | Select-Object -First 10
# - 11.获取可执行文件列表
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Process -Filter "NOT ExecutablePath LIKE '%Windows%'" | format-table ExecutablePath
# - 12.获取目录属性以及删除目录
Get-CimInstance -Namespace ROOTCIMV2 -Class win32_directory -filter "drive='f:' and filename='kk'" |select-object -first 10
Get-CimInstance -Namespace ROOTCIMV2 -Class win32_directory -filter"drive='f:' and filename='test'" |Invoke-CimMethod -Name delete
# - 13.用户账号管理以及用户组管理
Get-CimInstance -Namespace ROOTCIMV2 -Class win32_useraccount
# Name Caption AccountType SID Domain
# ---- ------- ----------- --- ------
# Administrator WEIYIGEEKAdministrator 512 S-1-5-21-923396991-33996... WEIYIGEEK
Get-CimInstance -Namespace ROOTCIMV2 -Class win32_useraccount-filter "name='%UserName%'" |Invoke-CimMethod -Name rename("newUserName") # 用户账号重命名
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_Group |format-table caption,InstallDate,LocalAccount,Domain,SID,Status # 获取SID
# - 14.系统的GIM之信息收集
Get-CimInstance -Namespace ROOTCIMV2 -Class win32_computersystem |select-object Name,Domain,Manufacturer,Model,Username,Roles # 获取系统角色、用户名和制造商
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_QuickFixEngineering |select-object Caption,Description,HotFixID,InstalledOn # 获取补丁信息
Get-CimInstance -Namespace ROOTSecurityCenter2 -Class AntiVirusProduct | select-object displayName,productState, pathToSignedProductExe # 获取反病毒产品详情
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_OnBoardDevice | select-object Desciption,DeviceType,Enabled,Status # 判断目标系统是否为虚拟机
# Desciption DeviceType Enabled Status
# ---------- ---------- ------- ------
# 3 False
# 7 False
Get-CimInstance -Namespace ROOTCIMV2 -classname Win32_DiskDrive # 磁盘信息查看
# DeviceID Caption Partitions Size Model
# -------- ------- ---------- ---- -----
# \.PHYSICALDRIVE0 ST1000DM010-2EP102 6 1000202273280 ST1000DM010-2EP102
# \.PHYSICALDRIVE1 WD Elements SE 25FE USB Device 1 1000169372160 WD Elements SE 25FE USB Device
Get-CimInstance -Namespace ROOTCIMV2 -Class Win32_NTEventlogFile -filter "logfilename='windows powershell'" |Invoke-CimMethod -Name ClearEventlog # 清理系统日志
3.Get-WmiObject - 获取 WMI 类有关信息
描述: 获取 Windows Management Instrumentation (WMI) 类的实例或有关可用类的信息。
Tips: 从 PowerShell 3.0 开始,此 cmdlet 已被Get-CimInstance.
Tips: Get-Alias gwmi
可以看到 gwmi 是 Get-WmiObject 的别名
语法参数:
代码语言:javascript复制Get-WmiObject [[-Class] <System.String>] [[-Property] <System.String[]>] [-Amended] [-AsJob] [-Authentication {Default | None | Connect | Call | Packet | PacketIntegrity | PacketPrivacy | Unchanged}] [-Authority <System.String>] [-ComputerName <System.String[]>] [-Credential <System.Management.Automation.PSCredential>] [-DirectRead] [-EnableAllPrivileges] [-Filter <System.String>] [-Impersonation {Default | Anonymous | Identify | Impersonate | Delegate}] [-Locale <System.String>] [-Namespace <System.String>] [-ThrottleLimit <System.Int32>] [<CommonParameters>]
Get-WmiObject [[-Class] <System.String>] [-Amended] [-AsJob] [-Authentication {Default | None | Connect | Call | Packet | PacketIntegrity | PacketPrivacy | Unchanged}] [-Authority <System.String>] [-ComputerName <System.String[]>] [-Credential <System.Management.Automation.PSCredential>] [-EnableAllPrivileges] [-Impersonation {Default | Anonymous | Identify | Impersonate | Delegate}] [-List] [-Locale <System.String>] [-Namespace <System.String>] [-Recurse] [-ThrottleLimit <System.Int32>] [<CommonParameters>]
Get-WmiObject [-Amended] [-AsJob] [-Authentication {Default | None | Connect | Call | Packet | PacketIntegrity | PacketPrivacy | Unchanged}] [-Authority <System.String>] [-ComputerName <System.String[]>] [-Credential <System.Management.Automation.PSCredential>] [-DirectRead] [-EnableAllPrivileges] [-Impersonation {Default | Anonymous | Identify | Impersonate | Delegate}] [-Locale <System.String>] [-Namespace <System.String>] -Query <System.String> [-ThrottleLimit <System.Int32>] [<CommonParameters>]
# 参数说明:
-ComputerName : 指定管理操作的目标计算机。输入完全限定域名(FQDN)、NetBIOS名称或IP地址。
-Authentication : WMI 连接的身份验证级别 (`Default, None, Connect, Call, Packet, PacketIntegrity, PacketPrivacy, Unchanged`)
-Credential : 默认是用户帐户名称系统会提示用户输入密码。
-Filter: 用WMI查询语言WQL的语法, 指定要用作筛选器的Where子句, 使用WMI查询语言(WQL)的语法。
简单示例:
代码语言:javascript复制# 1) 计算机相关信息获取、操作
Get-WmiObject Win32_UserAccount # 获取计算机中的账号 (可省略Class)
Get-WmiObject Win32_Processor # 获取CPU处理器信息
# Caption : Intel64 Family 6 Model 60 Stepping 3
# DeviceID : CPU0
# Manufacturer : GenuineIntel
# MaxClockSpeed : 3301
# Name : Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz
# SocketDesignation : SOCKET 0
Get-WmiObject -Class Win32_Process # 获取本地计算机上的进程。
Get-WmiObject -Class Win32_Bios | Format-List -Property * # 本地计算机获取 BIOS 信息
Get-WmiObject -class win32_OperatingSystem # 获取操作系统的信息
Get-WmiObject -Class Win32_OperatingSystem | Format-List BootDevice,BuildNumber,BuildType,Caption,CodeSet,CountryCode # 获取系统版本和系统是专业版还是教育版
Get-WmiObject -class win32_ComputerSystem # 获取计算机系统的信息
Get-WmiObject -class Win32_LogicalDisk # 获取计算机磁盘信息
Get-WMIObject -Class Win32_DiskDrive # 查看硬盘信息
Get-WmiObject -Class Win32_Product | Select-Object -Property Name,Version,IdentifyingNumber # 查看本机已安装的软件列表 (稍慢)
Get-WMIObject -Class Win32_PhysicalMemory # 获取内存信息
gwmi Win32_PhysicalMemory | %{$sum = 0} { $sum = $_.Capacity } {Write-Host ($sum / 1GB) "GB"} # GB为单位查询内存
Get-WmiObject win32_OperatingSystem FreePhysicalMemory # 查询空闲内存
Get-WmiObject -class Win32_NetworkAdapterConfiguration # 获取网络信息
gwmi Win32_PerfFormattedData_Tcpip_NetworkInterface | select Name,CurrentBandwidth # 获取网卡及带宽
gwmi Win32_DiskDrive | %{$sum = 0} { $sum = $_.Size } {Write-Host ($sum / 1GB) "GB"} # GB为单位查询硬盘 1862.99127101898 GB
Get-WmiObject Win32_LogicalDisk | Foreach-Object { 'Disk {0} has {1:0.0} MB space available' -f $_.Caption, ($_.FreeSpace / 1MB) } # 查询硬盘剩余空间
# 2) 远程计算机信息获取、操作
Get-WmiObject -Class Win32_Service -ComputerName 10.1.4.62 # 获取远程计算机上的服务
Get-WmiObject Win32_Service -Credential FABRIKAMadministrator -ComputerName Fabrikam # 远程计算机认证
(Get-WmiObject -Class Win32_Service -Filter "name='WinRM'" -ComputerName Server01).StopService() # 停止远程计算机上的WinRM服务,对该对象调用Win32_Service WMI 类的StopService方法 。
# 3) 在本地计算机的root/default、root/cimv2命名空间中获取 WMI 类
Get-WmiObject -Namespace "root/default" -List # NameSpace:ROOTdefault
Get-WmiObject -Namespace "root/cimv2" -List # NameSpace:ROOTCIMV2
# Name Methods Properties
# Win32_DeviceChangeEvent {} {EventType, SECURITY_DESCRIPTOR, TIME_CREATED}
# 4) 条件添加与WMI 类SQL查询语句 WMI Query Language (WQL).
Get-WmiObject Win32_LogicalDisk -filter "DeviceID = 'c:' " # 指定逻辑磁盘信息
Get-WmiObject win32_service -filter "name='WinRM'" # 指定服务信息
Get-WmiObject -Query "select * from win32_service where name='WinRM'" | Format-List -Property PSComputerName, Name, ExitCode, Name, ProcessID, StartMode, State, Status
# PSComputerName : WEIYIGEEK
# Name : WinRM
# ExitCode : 1077
# Name : WinRM
# ProcessID : 0
# StartMode : Manual
# State : Stopped
# Status : OK
# 5) 如何使用PowerShell查找Windows产品密钥?可以使用PowerShell或CMD检索Windows产品密钥。我们需要查询SoftwareLicesingService类,并且有一个名为OA3xOriginalProductKey 的属性来存储产品密钥。
Get-WmiObject -query 'select * from SoftwareLicensingService' | Select OA3xOriginalProductKey,ClientMachineID,KeyManagementServiceProductKeyID
# OA3xOriginalProductKey ClientMachineID KeyManagementServiceProductKeyID
# ---------------------- --------------- --------------------------------
# bf4de4ea-3318-494e-b37b-727fcae6492d 55041-00206-262-110359-03-6154-6002.0000-2512019
# 我们还可以使用cmd查询此WMI类如: wmic path softwarelicensingservice get OA3xOriginalProductKey # Windows 10 OA3xOriginalProductKey 此项为空
# 6) 三种方式进行获取当前机器温度
Get-CimInstance -Namespace ROOT/WMI -Class MSAcpi_ThermalZoneTemperature
wmic /namespace:\rootcimv2 PATH Win32_PerfFormattedData_Counters_ThermalZoneInformation get Temperature
# 方式1
$t = Get-WmiObject -Namespace "root/wmi" -ClassName MSAcpi_ThermalZoneTemperature # 获取计算机传感器获取到的开式Kelvin和摄氏度Celsius以及华氏度Fahrenheit
foreach ($temp in $t.CurrentTemperature)
{
$currentTempKelvin = $temp / 10
$currentTempCelsius = $currentTempKelvin - 273.15
$currentTempFahrenheit = ( 9/ 5 ) * $currentTempCelsius 32
Write-host $currentTempCelsius.ToString() "C" : $currentTempFahrenheit.ToString() "F" : $currentTempKelvin "K"
# 29.85 C : 85.73 F : 303 K
}
# 方式2
Get-CimInstance -Namespace ROOT/WMI -Class MSAcpi_ThermalZoneTemperature | % {
$currentTempKelvin = $_.CurrentTemperature / 10
$currentTempCelsius = $currentTempKelvin - 273.15
$currentTempFahrenheit = (9/5) * $currentTempCelsius 32
"InstanceName: " $_.InstanceName " ==>> " $currentTempCelsius.ToString() " 摄氏度(C); " $currentTempFahrenheit.ToString() " 华氏度(F) ; " $currentTempKelvin "开氏度(K)"
}
# 7) 系统补丁最后一次更新
(get-wmiobject -class win32_quickfixengineering).InstalledOn | Sort-Object | select -Last 1 # 2021年6月9日 0:00:00
语法示例:
简单示例: