Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學

Windows PowerShell 與 WMI 深度整合:從核心架構到自動化運維實戰

編輯:Windows XP 系統介紹

Windows PowerShell 不只是命令列殼層,更是建構於 .NET Framework 之上的自動化引擎。其對 WMI (Windows Management Instrumentation) 的原生深度整合,讓系統管理員能以物件導向方式查詢、操作、監控企業級 IT 基礎設施。本文從 WMI 核心架構切入,實戰演示 PowerShell 運用 WMI 的五大核心指令與進階模式。

WMI 核心三要素:Provider、Class、Namespace

  • Provider (提供者):連接管理資料源 (登錄表、登入事件、磁碟、網卡、Active Directory 等) 的 COM/DLL 組件,實作標準 WMI API。核心概念:Provider 才是真正干活的代碼。
  • Class (類別):描述管理物件的藍圖,定義屬性 (Properties)、方法 (Methods)、關聯 (Associations)。如 Win32_Process (進程)、Win32_LogicalDisk (邏輯磁碟)、Win32_Service (服務)。
  • Namespace (命名空間):Class 的邏輯容器,預設 Root\CIMV2 涵蓋絕大多數 Win32 管理類別。其他常見:Root\Default (系統預設)、Root\SecurityCenter (安全中心)、Root\Virtualization (Hyper-V)、Root\Microsoft\Windows\Storage (存儲)。

PowerShell 操作 WMI 的五大核心 Cmdlet

Cmdlet核心功能典型用途關鍵參數
Get-WmiObject (別名 gwmi)查詢 WMI 類別實例 (最常用)硬體資產盤點、服務狀態、事件日誌、進程監控、網路設定-Class, -Namespace, -ComputerName, -Filter (WQL), -Property, -Credential
Invoke-WmiMethod呼叫 WMI 類別/實例方法建立進程 (Win32_Process.Create)、啟動/停止服務 (Win32_Service.StartService/StopService)、重命名電腦 (Win32_ComputerSystem.Rename)-Name (方法名), -ArgumentList, -Path (實例路徑)
Register-WmiEvent訂閱 WMI 事件 (非同步監控)監控程式啟動/結束、USB 插拔、服務狀態變更、磁碟空間閾值、登入事件-Query (WQL 事件查詢), -Action (ScriptBlock), -SourceIdentifier, -Forward (轉發至引擎事件)
Remove-WmiObject刪除 WMI 類別實例 (非刪除類別定義)移除自訂 WMI 類別實例、清理殘留實例 (謹慎使用)-InputObject (管線傳入實例)
Set-WmiInstance建立或更新 WMI 類別實例 (寫入 WMI 儲存庫)修改網卡 IP/DNS、建立計劃任務、設定環境變數、配置防火牆規則 (需對應 Provider 支援寫入)-Arguments (雜湊表屬性值), -PutType (Create/Update/UpdateOnly)

實戰場景演示

1. 探索命名空間與類別:不知道有什麼類別怎麼辦?

# 列出根命名空間下的所有子命名空間
Get-WmiObject -Namespace "Root" -Class "__Namespace" | Select-Object Name

# 列出指定命名空間所有類別 (含單例/抽象)
Get-WmiObject -Namespace "Root\CIMV2" -List | Where-Object { $_.Name -like "Win32_*" } | Select-Object Name, Qualifiers

# 關鍵字過濾 (支援萬用字元)
Get-WmiObject -Namespace "Root\SecurityCenter2" -List *Firewall* | Format-Table Name, __Class -AutoSize

# 遠端查詢 (需 RPC/DCOM 通訊、防火牆開放、權限)
Get-WmiObject -Namespace "Root\Virtualization" -List -ComputerName "HyperV-Host01" -Credential (Get-Credential)

工具輔助: WMI Explorer (GUI)、PowerShell ISE 內建 Show-Command、Sapien PowerShell Studio 物件瀏覽器。

2. 企業級硬體資產自動掃描腳本

$computers = Get-Content "servers.txt"  # 或從 AD Get-ADComputer -Filter * | Select-Object -ExpandProperty DNSHostName
$results = foreach ($comp in $computers) {
    try {
        $cs = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $comp -ErrorAction Stop
        $bios = Get-WmiObject -Class Win32_BIOS -ComputerName $comp
        $os = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $comp
        $cpu = Get-WmiObject -Class Win32_Processor -ComputerName $comp
        $disk = Get-WmiObject -Class Win32_LogicalDisk -ComputerName $comp -Filter "DriveType=3" | Measure-Object -Property Size, FreeSpace -Sum
        $mem = Get-WmiObject -Class Win32_PhysicalMemory -ComputerName $comp | Measure-Object -Property Capacity -Sum

        [PSCustomObject]@{
            ComputerName = $comp
            Manufacturer = $cs.Manufacturer
            Model        = $cs.Model
            BIOSVersion  = $bios.SMBIOSBIOSVersion
            OSVersion    = $os.Caption + " " + $os.Version
            CPU          = "$($cpu.Name) ($($cpu.NumberOfLogicalProcessors) 邏輯核心)"
            TotalRAM_GB  = "{0:N1}" -f ($mem.Sum / 1GB)
            DiskTotal_GB = "{0:N1}" -f ($disk.Sum / 1GB)
            DiskFree_GB  = "{0:N1}" -f ($disk.FreeSpace / 1GB)
            ScanTime     = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        }
    } catch {
        Write-Warning "$comp 連線失敗: $($_.Exception.Message)"
        [PSCustomObject]@{ ComputerName=$comp; Error=$_.Exception.Message }
    }
}
$results | Export-Csv "Asset_Inventory_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation -Encoding UTF8

3. 事件驅動自動化:監控關鍵服務崩潰自動重啟並告警

$query = "SELECT * FROM __InstanceModificationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_Service' AND TargetInstance.Name = 'MSSQLSERVER' AND TargetInstance.State = 'Stopped'"
$action = {
    $svc = $Event.SourceEventArgs.NewEvent.TargetInstance
    Write-Host "[$(Get-Date)] 偵測到 $($svc.DisplayName) ($($svc.Name)) 服務停止,嘗試重啟..."
    Invoke-WmiMethod -Path "Win32_Service.Name='$($svc.Name)'" -Name StartService -ComputerName $svc.__SERVER -Credential $cred
    # 發送郵件/Teams/Slack 告警 (略)
}
Register-WmiEvent -Query $query -Action $action -SourceIdentifier "Monitor_MSSQL_Service" -Credential $cred
# 持續運行... 結束時: Unregister-Event -SourceIdentifier "Monitor_MSSQL_Service"

4. 遠端批次修改靜態 IP/DNS (需目標機啟用 WinRM/WMI 寫入權限)

$nic = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -ComputerName "TargetPC" -Filter "IPEnabled=TRUE" -Credential $cred
$nic.EnableStatic($ipAddress, $subnetMask)
$nic.SetDNSServerSearchOrder($dnsServers)

進階:CIM Cmdlet (PowerShell 3.0+) — 現代化替代者

WMI Cmdlet (Get-WmiObject 等) 基於 DCOM/RPC,跨網段/NAT/防火牆困難。CIM Cmdlet (Get-CimInstance, Invoke-CimMethod, Register-CimIndicationEvent, New-CimSession) 基於 WS-MAN (WinRM/HTTP/HTTPS),支援會話、遠端更穩健、效能更好、標準化。

# 建立 CIM 會話 (可重用、支援 Kerberos/SSL)
$session = New-CimSession -ComputerName "Server01", "Server02" -Credential $cred -Authentication Kerberos
Get-CimInstance -ClassName Win32_Service -CimSession $session -Filter "State='Running' AND StartMode='Auto'" | Select-Object Name, DisplayName, State, StartMode
Remove-CimSession $session

最佳實踐: 新腳本優先使用 CIM Cmdlet;維護舊腳本或需 DCOM 特定功能時使用 WMI Cmdlet。

總結:PowerShell + WMI/CIM = 基礎設施即代碼

掌握 Namespace/Class/Provider 架構、善用 Get/Invoke/Register/Remove/Set 五大核心操作、結合 WQL 過濾、遠端會話、事件訂閱、物件管線,即可將繁瑣手工運維轉化為可版控、可測試、可複用的自動化資產。從「會用指令」進化到「設計自動化系統」,是邁向 DevOps/SRE 的關鍵一步。

Copyright © Windows教程網 All Rights Reserved