本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
PowerShellクラスを活用したマルチノード・インベントリ収集の構造化
【導入:解決する課題】
煩雑なサーバー情報の収集を、クラス定義によるデータ構造の統一と並列処理によって、高速かつメンテナブルに自動化します。
【設計方針と処理フロー】
本スクリプトでは、.NETライクな「PowerShellクラス」をデータモデルとして採用します。これにより、従来のハッシュテーブルでは曖昧になりがちだったプロパティ型を厳密に定義し、大規模環境でも予見可能性の高いコードを実現します。
graph TD
A[Start] --> B["ターゲットリストの読み込み"]
B --> C["クラスインスタンスの初期化"]
C --> D{"並列処理開始"}
D --> E["CIM/WMIによるリモート情報取得"]
E --> F["取得結果をクラスプロパティに格納"]
F --> G{"全ノード完了?"}
G -- No --> E
G -- Yes --> H["カスタムオブジェクトの集計出力"]
H --> I[Finish]
【実装:コアスクリプト】
以下は、PowerShell 7.xの ForEach-Object -Parallel を活用し、並列性を確保しながらクラスベースのデータ管理を行う実装例です。
# クラス定義:データの整合性を保証
class ServerInventory {
[string]$ComputerName
[string]$OSVersion
[decimal]$TotalMemoryGB
[string]$Status
[DateTime]$LastChecked
ServerInventory([string]$name) {
$this.ComputerName = $name
$this.LastChecked = [DateTime]::Now
$this.Status = "Pending"
}
[void]UpdateInfo([string]$os, [decimal]$mem) {
$this.OSVersion = $os
$this.TotalMemoryGB = [Math]::Round($mem / 1GB, 2)
$this.Status = "Success"
}
[void]MarkFailed([string]$message) {
$this.Status = "Failed: $message"
}
}
function Get-RemoteInventory {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string[]]$ComputerNames,
[int]$ThrottleLimit = 10
)
# PowerShell 7以降の並列処理を利用
$results = $ComputerNames | ForEach-Object -Parallel {
$node = [ServerInventory]::new($_)
try {
# CIMによる情報取得(標準的な管理プロトコル)
$osInfo = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $_ -ErrorAction Stop
$node.UpdateInfo($osInfo.Caption, $osInfo.TotalVisibleMemorySize * 1024)
}
catch {
$node.MarkFailed($_.Exception.Message)
}
return $node
} -ThrottleLimit $ThrottleLimit
return $results
}
# 実行例
$targetList = @("Server01", "Server02", "localhost") # 環境に合わせて変更
$inventoryData = Get-RemoteInventory -ComputerNames $targetList
$inventoryData | Format-Table -AutoSize
【検証とパフォーマンス評価】
従来の foreach ループによる逐次処理と、ForEach-Object -Parallel を用いた本手法のパフォーマンスを比較します。
検証コード例:
Measure-Command { Get-RemoteInventory -ComputerNames (1..50 | % { "DummyServer$_" }) }期待値:
逐次処理: ノード数 × タイムアウト(30秒程度)= 数十分
本手法 (ThrottleLimit 10): 並列実行により、ボトルネックとなるネットワーク待機時間を大幅に短縮(約1/5〜1/10の時間で完了)。
メモリ効率: ハッシュテーブルと比較し、型定義されたクラスは大規模なデータセット(数千ノード)においてメモリフットプリントが安定する傾向にあります。
【運用上の落とし穴と対策】
PowerShell バージョンの壁:
class構文は PowerShell 5.0+ で動作しますが、ForEach-Object -Parallelは PowerShell 7.0+ 専用です。Windows PowerShell 5.1 環境ではRunspacesまたはWorkflows(非推奨) への置換検討が必要です。
型厳格性によるエラー:
- クラスのプロパティに想定外の型(nullや空文字)を代入しようとすると例外が発生します。
UpdateInfoメソッド内での事前バリデーションを推奨します。
- クラスのプロパティに想定外の型(nullや空文字)を代入しようとすると例外が発生します。
認証と接続の制約:
- WinRMが有効でない環境では
Get-CimInstanceが失敗します。事前にTest-WSManによる疎通確認をフローに組み込むことが実務上重要です。
- WinRMが有効でない環境では
【まとめ】
型定義による品質担保: クラスを利用することで、後続の集計処理(CSV出力やDB登録)での型エラーを未然に防ぐ。
並列処理による時間短縮: リモートインベントリ収集のようなI/O待ちが発生する処理は、
Parallelスイッチで効率化する。例外処理の構造化: クラスメソッド内にエラー状態(Failed)をカプセル化し、呼び出し元でのエラーハンドリングを簡素化する。

