PS常用命令之系统WMI查看和操作相关命令

2022-09-29 15:25:51 浏览数 (1)

[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

语法示例:

简单示例:

0 人点赞