CIM/WMIを活用した分散端末の状態監視・イベントログ集約自動化

Tech

  • ROLE: シニアPowerShellエンジニア(Windows/Linux運用エキスパート)

  • LANGUAGE: 日本語(専門用語は正確に、解説は簡潔かつロジカルに)

  • TECH-STACK: PowerShell 7.x (Core) & 5.1 (Desktop), CIM Cmdlets, WS-Man, .NET Core/Framework

  • FOCUS: CIMインスタンスを用いた非同期取得、WS-Manプロトコルの最適化、大規模環境でのスケーラビリティ

  • POLICY: Get-WmiObjectを廃止し、DCOM/WS-Man両対応のCIMコマンドレットを推奨。エラーハンドリングは具体的に記述。 本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

CIM/WMIを活用した分散端末の状態監視・イベントログ集約自動化

【導入:解決する課題】

リモートPCの稼働状況と致命的エラーを一括取得し、管理者が手動で行っていた巡回点検工数を最小化します。

【設計方針と処理フロー】

本スクリプトでは、旧来の Get-WmiObject (DCOM依存) を避け、最新の Get-CimInstance (WS-Man対応) を採用します。これにより、ファイアウォール親和性を高め、PS 7.x 環境での ForEach-Object -Parallel による高速な並列処理を実現します。

graph TD
A[Start] --> B["Target Computer List"]
B --> C{"Test Connection"}
C -->|Online| D["Parallel CIM Session"]
C -->|Offline| E["Log Offline Status"]
D --> F["Query OS/CPU/Disk Info"]
F --> G["Fetch Error Event Logs"]
G --> H["Standardize Objects"]
H --> I["Export JSON/CSV"]
I --> J[Finish]

【実装:コアスクリプト】

以下は、並列処理(PowerShell 7以降推奨)と厳格なエラー制御を組み込んだ監視スクリプトのプロトタイプです。

function Get-RemoteSystemHealth {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string[]]$ComputerName,

        [Parameter()]
        [int]$MaxConcurrency = 10,

        [Parameter()]
        [int]$EventLogLimit = 5
    )

    process {
        $results = $ComputerName | ForEach-Object -Parallel {
            $comp = $_
            $report = [PSCustomObject]@{
                Timestamp    = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
                ComputerName = $comp
                Status       = "Success"
                OSCaption    = $null
                CpuUsage     = $null
                FreeDiskGB   = $null
                RecentErrors = @()
                ErrorMessage = $null
            }

            try {

                # 接続確認 (Timeout 2s)

                if (-not (Test-Connection -ComputerName $comp -Count 1 -Quiet)) {
                    throw "Node unreachable."
                }

                # CIMセッションのオプション設定 (WS-Man)

                $sessionOption = New-CimSessionOption -Protocol Wsman
                $session = New-CimSession -ComputerName $comp -SessionOption $sessionOption -ErrorAction Stop

                # システム情報の取得

                $os = Get-CimInstance -CimSession $session -ClassName Win32_OperatingSystem
                $report.OSCaption = $os.Caption

                # ディスク空き容量 (Cドライブのみ抽出)

                $disk = Get-CimInstance -CimSession $session -ClassName Win32_LogicalDisk -Filter "DeviceID='C:'"
                $report.FreeDiskGB = [math]::Round($disk.FreeSpace / 1GB, 2)

                # CPU使用率 (直近値)

                $cpu = Get-CimInstance -CimSession $session -ClassName Win32_Processor
                $report.CpuUsage = $cpu.LoadPercentage

                # イベントログの取得 (SystemログのErrorレベルを抽出)

                $errors = Get-WinEvent -ComputerName $comp -LogName System -MaxEvents $using:EventLogLimit `
                          -FilterHashtable @{Level=2} -ErrorAction SilentlyContinue

                if ($errors) {
                    $report.RecentErrors = $errors | ForEach-Object { $_.Message.Trim() }
                }

                Remove-CimSession $session
            }
            catch {
                $report.Status = "Failed"
                $report.ErrorMessage = $_.Exception.Message
            }

            return $report
        } -ThrottleLimit $MaxConcurrency

        return $results
    }
}

# 実行例


# $targets = Get-Content "./server_list.txt"


# Get-RemoteSystemHealth -ComputerName $targets | ConvertTo-Json | Out-File "./report.json"

【検証とパフォーマンス評価】

  • 計測方法: Measure-Command { Get-RemoteSystemHealth -ComputerName (1..50) } を実行。

  • 期待値: ForEach-Object -Parallel を使用しない場合、50台のシーケンシャル処理で約5〜10分を要するが、並列度10の設定では1分前後(ネットワーク遅延に依存)まで短縮可能。

  • スケーラビリティ: MaxConcurrency を調整することで、コア数に応じた最適化が可能。

【運用上の落とし穴と対策】

  1. WinRMの未構成: CIM/WS-Manを利用するため、対象側で Enable-PSRemoting が必須。拒否される場合は GPO での「Windows リモート管理」の許可が必要。

  2. PowerShell 5.1との互換性: 上記スクリプトの -Parallel スイッチは PowerShell 7 専用。5.1 環境では Start-Job または Workflow (非推奨) への書き換えが必要。

  3. 文字化け (Encoding): Get-WinEvent のメッセージに含まれる日本語が化ける場合、出力時に Out-File -Encoding utf8 を明示すること(PS 7は既定でUTF-8)。

  4. ダブルホップ問題: リモートPCからさらに別のサーバーのリソースを触る場合、CredSSP または Kerberos 委任の設定が必要。

【まとめ】

  1. CIMへの移行: Get-WmiObject を捨て、ファイアウォール対応が容易な Get-CimInstance を標準とする。

  2. 並列化の活用: 大規模環境では ForEach-Object -Parallel でスループットを向上させる。

  3. 例外の構造化: try/catch を用い、オフライン端末があっても全体の処理を止めない堅牢なコードを記述する。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました