CIMセッションと並列処理によるリモートPC状態監視の自動化

Tech

{“version”: “1.0”, “role”: “Senior PowerShell Engineer”, “focus”: “WMI/CIM/WinRM Remote Management”, “style”: “Technical/Professional”} 本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。

CIMセッションと並列処理によるリモートPC状態監視の自動化

【導入:解決する課題】

管理対象となる数百台のPCに対し、個別のログインやRDP接続を行うことなく、システムリソース(CPU/メモリ/ディスク)と致命的なイベントログを数秒で一括収集し、障害の早期発見を可能にします。

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

本スクリプトでは、従来の Get-WmiObject (DCOM/RPC) ではなく、最新の標準である CIM コマンドレット (WS-Man) を採用します。これにより、Firewallフレンドリーな通信と New-CimSession によるセッション再利用、さらに ForEach-Object -Parallel による高速な並列処理を実現します。

graph TD
Start["監視開始"] --> LoadPC["PCリスト読み込み"]
LoadPC --> CreateSession["CIMセッションの確立"]
CreateSession --> ParallelProcess{"並列処理開始"}
ParallelProcess --> GetOS["OS/メモリ情報取得"]
ParallelProcess --> GetDisk["ディスク空き容量取得"]
ParallelProcess --> GetEvent["重大なイベントログ取得"]
GetOS --> Combine["オブジェクト統合"]
GetDisk --> Combine
GetEvent --> Combine
Combine --> LogOutput["CSV/JSON出力"]
LogOutput --> End["終了"]

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

※PowerShell 7.x 環境での実行を推奨しますが、5.1でも CIM コマンドレットは動作します(並列処理部分のみ要調整)。

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

        [Parameter(Mandatory=$false)]
        [pscredential]$Credential
    )

    # 1. セッションの作成(コネクションプーリングによる効率化)

    $sessionOptions = New-CimSessionOption -Protocol Wsman -Culture en-US
    $sessions = New-CimSession -ComputerName $ComputerNames -Option $sessionOptions -Credential $Credential -ErrorAction SilentlyContinue

    # 2. 並列処理によるデータ収集

    $results = $sessions | ForEach-Object -Parallel {
        $computer = $_.ComputerName
        try {

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

            $os = Get-CimInstance -CimSession $_ -ClassName Win32_OperatingSystem

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

            $disk = Get-CimInstance -CimSession $_ -ClassName Win32_LogicalDisk -Filter "DeviceID='C:'"

            # 直近24時間のCritical/Errorイベントログ取得

            $logFilter = @{
                LogName = 'System'
                Level = 1,2 # Critical, Error
                StartTime = (Get-Date).AddDays(-1)
            }
            $events = Get-WinEvent -ComputerName $computer -FilterHashtable $logFilter -ErrorAction SilentlyContinue

            # 結果の統合

            [PSCustomObject]@{
                PSComputerName = $computer
                Status         = "Success"
                OSName         = $os.Caption
                FreeMemoryGB   = [Math]::Round($os.FreePhysicalMemory / 1MB, 2)
                DiskFreePercent = [Math]::Round(($disk.FreeSpace / $disk.Size) * 100, 2)
                ErrorLogCount  = if($events) { $events.Count } else { 0 }
                LastBootUpTime = $os.LastBootUpTime
                Timestamp      = Get-Date
            }
        }
        catch {
            [PSCustomObject]@{
                PSComputerName = $computer
                Status         = "Failed: $($_.Exception.Message)"
                Timestamp      = Get-Date
            }
        }
    } -ThrottleLimit 20

    # セッションのクリーンアップ

    $sessions | Remove-CimSession

    return $results
}

# 実行例


# $nodes = Get-Content "./ServerList.txt"


# Get-RemoteSystemHealth -ComputerNames $nodes | Export-Csv -Path "./HealthCheck_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation

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

  • 計測手法: Measure-Command { Get-RemoteSystemHealth -ComputerNames (1..50) }

  • 期待値:

    • 逐次処理(PS 5.1): 約 150~300秒(タイムアウト待ちを含む)。

    • 並列処理(PS 7.x / Throttle 20): 約 20~40秒。

  • スケーラビリティ: ThrottleLimit を調整することで、ネットワーク帯域や管理サーバーのCPUリソースに応じた最適化が可能です。

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

  1. WinRMの未有効化:

    • 対策: Enable-PSRemoting が対象PCで実行されている必要があります。GPOによる一括設定が推奨されます。
  2. Double Hop問題:

    • 対策: 収集データをさらに別のファイルサーバーへ転送する場合、CredSSPやCIMセッション経由の認証情報の委譲設定が必要です。
  3. WMIリポジトリの破損:

    • 対策: Get-CimInstance がタイムアウトする場合、WMIリポジトリの再構築(winmgmt /salvagerepository)が必要な個体がある可能性があります。
  4. 文字コード問題:

    • 対策: PowerShell 5.1でCSV出力する場合、Export-Csv -Encoding UTF8 を明示しないと、日本語(Caption等)が文字化けします。

【まとめ】

  1. CIMへの移行: Get-WmiObject は非推奨。Get-CimInstanceCimSession を活用してパフォーマンスを最大化する。

  2. 並列化の活用: 大規模環境では ForEach-Object -Parallel を使い、待ち時間を最小化する。

  3. エラーハンドリング: 疎通確認(Test-Connection)よりも、try-catch によるセッション作成失敗のハンドリングの方が実戦的で高速。

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

コメント

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