{“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リソースに応じた最適化が可能です。
【運用上の落とし穴と対策】
WinRMの未有効化:
- 対策:
Enable-PSRemotingが対象PCで実行されている必要があります。GPOによる一括設定が推奨されます。
- 対策:
Double Hop問題:
- 対策: 収集データをさらに別のファイルサーバーへ転送する場合、CredSSPやCIMセッション経由の認証情報の委譲設定が必要です。
WMIリポジトリの破損:
- 対策:
Get-CimInstanceがタイムアウトする場合、WMIリポジトリの再構築(winmgmt /salvagerepository)が必要な個体がある可能性があります。
- 対策:
文字コード問題:
- 対策: PowerShell 5.1でCSV出力する場合、
Export-Csv -Encoding UTF8を明示しないと、日本語(Caption等)が文字化けします。
- 対策: PowerShell 5.1でCSV出力する場合、
【まとめ】
CIMへの移行:
Get-WmiObjectは非推奨。Get-CimInstanceとCimSessionを活用してパフォーマンスを最大化する。並列化の活用: 大規模環境では
ForEach-Object -Parallelを使い、待ち時間を最小化する。エラーハンドリング: 疎通確認(Test-Connection)よりも、
try-catchによるセッション作成失敗のハンドリングの方が実戦的で高速。

コメント