リモートPCの統合監視:CIMセッションによるシステム診断とイベントログ抽出の自動化

Tech

【執筆スタイル:シニアPowerShellエンジニア】

  • 冗長な挨拶を排除し、即座に技術的解決策を提示する。

  • WMI(旧式)ではなくCIM(モダン)を推奨し、その理由を暗黙的に実装で示す。

  • スクリプトは「コピー&ペーストで動作する」だけでなく「堅牢なエラーハンドリング」を備えた実戦仕様とする。

  • パフォーマンス(並列処理、セッション管理)に妥協しない。

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

リモートPCの統合監視:CIMセッションによるシステム診断とイベントログ抽出の自動化

【導入:解決する課題】

大規模ネットワーク内にある複数台のリモートPCに対し、ログインすることなくOSの状態、ディスク残量、および直近の致命的エラー(イベントログ)を一括取得し、運用監視の工数を劇的に削減します。

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

本スクリプトは、WinRMを利用したCIM(Common Information Model)セッションを確立し、単一のパイプラインで「ハードウェア情報」と「OSログ」を並列的に処理する設計を採用します。

graph TD
A["Start: ターゲットリストの読み込み"] --> B["New-CimSession: セッションの確立"]
B --> C{"接続確認"}
C -->|成功| D["Get-CimInstance: CPU/メモリ/ディスク情報の取得"]
D --> E["Get-WinEvent: 過去24時間のError/Criticalログ抽出"]
E --> F["PSCustomObject: データの集約"]
C -->|失敗| G["ErrorLog: 接続失敗として記録"]
F --> H["Export-Csv/Display: 結果の出力"]
G --> H
H --> I["Remove-CimSession: セッションの破棄"]
I --> J[End]

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

PowerShell 7.x 以降の並列処理(-Parallel)を活用した、高効率な監視スクリプトです。5.1環境の場合は ForEach-Object -Parallel 部分を通常の foreach に置き換えてください。

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

        [Parameter()]
        [int]$EventLookbackHours = 24
    )

    # 接続オプションの設定(WinRM/WS-Man)

    $sessionOption = New-CimSessionOption -Protocol Wsman -ConnectTimeoutMs 5000

    # 並列処理による一括実行

    $results = $ComputerNames | ForEach-Object -Parallel {
        $computer = $_
        $report = [PSCustomObject]@{
            Timestamp    = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            ComputerName = $computer
            OS           = "N/A"
            FreeDiskGB   = 0
            MemUsage     = "N/A"
            RecentErrors = 0
            Status       = "Success"
        }

        try {
            $session = New-CimSession -ComputerName $computer -SessionOption $using:sessionOption -ErrorAction Stop

            # OS情報の取得

            $os = Get-CimInstance -CimSession $session -ClassName Win32_OperatingSystem
            $report.OS = $os.Caption
            $report.MemUsage = "{0:P2}" -f ((($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize))

            # ディスク残量(Cドライブ)の取得

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

            # イベントログ(エラー/重大)の抽出

            $startTime = (Get-Date).AddHours(-$using:EventLookbackHours)
            $filter = @{
                LogName = 'System'
                Level   = 1, 2 # 1:Critical, 2:Error
                StartTime = $startTime
            }
            $errorLogs = Get-WinEvent -ComputerName $computer -FilterHashtable $filter -ErrorAction SilentlyContinue
            $report.RecentErrors = ($errorLogs | Measure-Object).Count

        } catch {
            $report.Status = "Failed: $($_.Exception.Message)"
        } finally {
            if ($session) { Remove-CimSession $session }
        }

        return $report
    } -ThrottleLimit 10

    return $results
}

# 実行例


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


# Get-RemoteSystemHealth -ComputerNames $targets | Out-GridView

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

  • 計測手法: Measure-Command { Get-RemoteSystemHealth -ComputerNames $list } を使用。

  • 期待値: CIMセッションはRPC(WMI)と比較して接続オーバーヘッドが少なく、10台程度の同時実行であれば -Parallel により数秒で完了します。

  • スケールアウト: ThrottleLimit を調整することで、数百台規模の環境でもネットワーク帯域とサーバーCPU負荷を制御しながら実行可能です。

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

  1. WinRMの有効化: リモートPC側で Enable-PSRemoting が実行されている必要があります。未設定の場合は接続エラーとなります。

  2. PowerShell 5.1互換性: 標準の Get-WinEvent はDCOMを使用する場合がありますが、本スクリプトのように CimSession を介さない場合はファイアウォール設定(RPC)に注意が必要です。

  3. 文字コード: Export-Csv を行う際は、Excelでの閲覧を考慮し -Encoding UTF8(PS7)または -Encoding Default(PS5.1)を明示してください。

  4. ダブルホップ問題: 取得データをさらに別のサーバーに保存する場合、認証の委譲問題が発生します。

【まとめ】

  1. CIM/WS-Manを優先せよ: 従来のWMI(DCOM)はファイアウォールでブロックされやすく、モダンなCIMセッションの方が安定します。

  2. セッション管理の徹底: 接続後に Remove-CimSession で明示的にセッションを閉じ、リモートリソースを解放してください。

  3. 例外処理は具体的に: ネットワーク断、権限不足、WinRM未設定など、失敗理由を Status フィールドに残すことで後続の調査が容易になります。

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

コメント

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