PowerShell/CIMによるマルチノード・リモート死活監視とイベント収集の自動化

Tech

[Identity] Senior PowerShell Engineer (Windows/Linux Ops) [Focus] Remote Management, CIM/WMI, Parallel Processing, Scalability [Logic] WinRM Session -> CIM Instance Collection -> Event Filter -> Exception Handling -> Object Export [Status] Draft (Unverified)

本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

PowerShell/CIMによるマルチノード・リモート死活監視とイベント収集の自動化

【導入:解決する課題】

複数拠点に点在するWindows端末の負荷状況と致命的なエラーログを一括取得し、管理者が1台ずつログインして確認する手間と工数を劇的に削減します。

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

本スクリプトは、レガシーな Get-WmiObject (RPC) ではなく、モダンな Get-CimInstance (WS-Man) を採用します。これにより、ファイアウォール親和性を高め、ForEach-Object -Parallel による高速な並列スキャンを実現します。

graph TD
A[Start] --> B["Target Computer List"]
B --> C{"Parallel Execution?"}
C -->|Yes| D[New-CimSession]
D --> E["Query: Win32_OperatingSystem / LogicalDisk"]
E --> F["Query: Win32_NTLogEvent / Get-WinEvent"]
F --> G["Error Handling / Logging"]
G --> H["Consolidate Results"]
H --> I[Finish]

CIMセッションを事前に確立することで、複数のクエリを単一のコネクションで実行し、オーバーヘッドを最小化する設計です。

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

以下は、PowerShell 7.x 以上の並列処理機能を前提とした、実戦的な監視スクリプトのテンプレートです。

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

        [int]$MaxConcurrency = 10,
        [int]$EventHours = 24
    )

    $ComputerNames | ForEach-Object -Parallel {
        $Computer = $_
        $Result = [PSCustomObject]@{
            ComputerName = $Computer
            Timestamp    = Get-Date
            OSStatus     = "Failed"
            FreeDiskGB   = $null
            CriticalLogs = 0
            ErrorMessage = $null
        }

        try {

            # CIMセッションの確立(WinRM)

            $SessionOption = New-CimSessionOption -Protocol Wsman -ConnectTimeoutMS 5000
            $Session = New-CimSession -ComputerName $Computer -SessionOption $SessionOption -ErrorAction Stop

            # OS情報の取得(稼働時間・メモリ)

            $OS = Get-CimInstance -CimSession $Session -ClassName Win32_OperatingSystem

            # ディスク情報の取得(Cドライブの空き容量)

            $Disk = Get-CimInstance -CimSession $Session -Query "SELECT FreeSpace FROM Win32_LogicalDisk WHERE DeviceID = 'C:'"

            # イベントログの取得(過去N時間のSystemログ: Error/Criticalのみ)

            $FilterHash = @{
                LogName = 'System'
                Level   = 1, 2 # 1:Critical, 2:Error
                StartTime = (Get-Date).AddHours(-$using:EventHours)
            }

            # CIMセッション経由でGet-WinEventを実行

            $Events = Get-WinEvent -FilterHashtable $FilterHash -ComputerName $Computer -ErrorAction SilentlyContinue

            # オブジェクトの組み立て

            $Result.OSStatus     = "Healthy"
            $Result.FreeDiskGB   = [Math]::Round($Disk.FreeSpace / 1GB, 2)
            $Result.CriticalLogs = if ($Events) { $Events.Count } else { 0 }

        } catch {
            $Result.ErrorMessage = $_.Exception.Message
        } finally {
            if ($Session) { Remove-CimSession $Session }
            $Result
        }
    } -ThrottleLimit $MaxConcurrency
}

# 実行例


# $Targets = Get-Content "C:\Path\To\Servers.txt"


# $Report = Get-RemoteSystemHealth -ComputerNames $Targets


# $Report | Export-Csv -Path ".\SystemHealthReport.csv" -NoTypeInformation -Encoding utf8

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

100台のリモートPCに対し、逐次(Sequential)処理と並列(Parallel)処理で実行時間を比較した場合の期待値は以下の通りです。

  • 逐次処理: 約300秒〜500秒(1台あたり3〜5秒のタイムアウト待ちを含むため)

  • 並列処理 ($MaxConcurrency = 20): 約30秒〜50秒

  • 評価: Get-CimInstanceNew-CimSession を再利用することで、同一ホストへの複数問い合わせを高速化できます。また、Get-WinEventFilterHashtable は、クライアント側ではなくサーバ側でフィルタリングを行うため、ネットワークトラフィックを大幅に抑制します。

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

  1. WinRMの未有効化: リモート実行には Enable-PSRemoting が必須です。GPOによる一括設定が推奨されます。

  2. PowerShell 5.1の互換性: ForEach-Object -Parallel は PS 7以降の機能です。PS 5.1環境では Start-JobRunspaces を使用するか、逐次処理に変更する必要があります。

  3. ダブルホップ問題: 取得したログをさらに別の共有フォルダに保存する場合など、資格情報の委譲(CredSSP)が必要になるケースがあります。

  4. 時刻同期: StartTime を指定する際、操作端末とリモート端末の時刻がズレていると、正確なログ範囲を取得できないため、NTP同期が前提となります。

【まとめ】

  1. CIMへの移行: RPC(WMI)を避け、WinRM(CIM)を利用してセキュリティと透過性を確保する。

  2. サーバーサイドフィルタ: FilterHashtable を活用し、必要なデータのみを最小限のトラフィックで取得する。

  3. 並列化の制御: ThrottleLimit を適切に設定し、管理端末側のリソース枯渇を防ぐ。

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

コメント

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