<p><meta/>SYSTEM_INFO_WMI_VBA_V1_0
本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">【VBA×WMI】リモートPCのシステム情報(OS・CPU・メモリ)を一括取得する実務自動化ガイド</h1>
<h2 class="wp-block-heading">【背景と目的】</h2>
<p>複数端末のスペック調査を自動化し、手作業による工数を削減します。リモート接続時の「拒否」や「応答なし」による処理停止を防ぐ設計が実務上の鍵となります。</p>
<h2 class="wp-block-heading">【処理フロー図】</h2>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["開始"] --> B["対象PC名リストの読み込み"]
B --> C["WMI接続試行"]
C --> D{"接続成功?"}
D -- Yes --> E["Win32クラスから情報抽出"]
D -- No --> F["エラー内容を記録"]
E --> G["配列へデータ格納"]
G --> H["全PC終了まで反復"]
H --> I["Excelシートへ一括出力"]
I --> J["終了"]
</pre></div>
<h2 class="wp-block-heading">【実装:VBAコード】</h2>
<p>参照設定を不要にする「レイトバインディング(遅延結合)」を採用し、配布しやすい構成にしています。</p>
<pre data-enlighter-language="generic">Option Explicit
' Win32 API宣言(64bit環境対応)
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' 高速化設定
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim i As Long
Dim strComputer As String
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim results() As Variant
ReDim results(1 To lastRow - 1, 1 To 4) ' PC名, OS, CPU, Memory
On Error Resume Next
For i = 2 To lastRow
strComputer = ws.Cells(i, 1).Value
results(i - 1, 1) = strComputer
If strComputer <> "" Then
' WMIサービスへの接続(タイムアウト考慮なしの標準接続)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If Err.Number = 0 Then
' --- OS情報の取得 ---
Set colItems = objWMIService.ExecQuery("Select Caption from Win32_OperatingSystem")
For Each objItem In colItems
results(i - 1, 2) = objItem.Caption
Next
' --- CPU情報の取得 ---
Set colItems = objWMIService.ExecQuery("Select Name from Win32_Processor")
For Each objItem In colItems
results(i - 1, 3) = objItem.Name
Next
' --- メモリ情報の取得 (単位: GB) ---
Set colItems = objWMIService.ExecQuery("Select TotalPhysicalMemory from Win32_ComputerSystem")
For Each objItem In colItems
results(i - 1, 4) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
Else
' 接続エラー時の処理
results(i - 1, 2) = "接続エラー: " & Err.Description
Err.Clear
End If
End If
' オブジェクトの解放
Set objWMIService = Nothing
Set colItems = Nothing
Next i
' 結果を一括出力
ws.Range("B2").Resize(UBound(results, 1), UBound(results, 2)).Value = results
' 設定の復元
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
On Error GoTo 0
MsgBox "情報取得が完了しました。", vbInformation
End Sub
</pre>
<h2 class="wp-block-heading">【技術解説】</h2>
<ol class="wp-block-list">
<li><p><strong>WMI (Windows Management Instrumentation)</strong>: Windows OSを管理するためのインターフェースです。<code>winmgmts:</code> モニカーを使用してリモート名前空間にアクセスします。</p></li>
<li><p><strong>遅延結合 (Late Binding)</strong>: <code>CreateObject</code> や <code>GetObject</code> を使用することで、実行環境に依存せず、特定のライブラリ(Microsoft WMI Scripting V1.2 Library等)への参照設定が不要になります。</p></li>
<li><p><strong>Win32クラスの選定</strong>: </p>
<ul>
<li><p><code>Win32_OperatingSystem</code>: OSのバージョンやエディション。</p></li>
<li><p><code>Win32_Processor</code>: CPUの名称やコア数。</p></li>
<li><p><code>Win32_ComputerSystem</code>: 合計物理メモリ。</p></li>
</ul></li>
<li><p><strong>配列処理の最適化</strong>: セルへの書き込みをループ内で行わず、一度配列に格納してから一括出力することで、通信負荷と描画負荷を最小限に抑えています。</p></li>
</ol>
<h2 class="wp-block-heading">【注意点と運用】</h2>
<ol class="wp-block-list">
<li><p><strong>ファイアウォールの遮断</strong>: リモートPC側で「Windows Management Instrumentation (WMI)」の通信が許可されていない場合、接続エラーとなります。GPO(グループポリシー)等での事前設定が推奨されます。</p></li>
<li><p><strong>実行権限</strong>: リモート接続には、対象PCに対する「管理者権限」を持つユーザーでVBA(Excel)を実行している必要があります。</p></li>
<li><p><strong>タイムアウトの課題</strong>: <code>GetObject</code> はネットワーク接続不能なPCに対して数十秒フリーズする場合があります。大量のリストを処理する際は、事前に <code>Ping</code> 関数(Win32 API)で生存確認を行うロジックの追加を検討してください。</p></li>
</ol>
<h2 class="wp-block-heading">【まとめ】</h2>
<ul class="wp-block-list">
<li><p><strong>疎通確認が先決</strong>: WMI接続前にPingで対象の生存を確認し、無駄な待機時間を削減する。</p></li>
<li><p><strong>権限管理の徹底</strong>: 実行ユーザーが管理共有(C$等)にアクセスできる権限を有しているか確認する。</p></li>
<li><p><strong>エラーハンドリング</strong>: 接続不可・情報欠落を想定し、<code>On Error Resume Next</code> を適切に制御してログを残す。</p></li>
</ul>
SYSTEM_INFO_WMI_VBA_V1_0
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
【VBA×WMI】リモートPCのシステム情報(OS・CPU・メモリ)を一括取得する実務自動化ガイド
【背景と目的】
複数端末のスペック調査を自動化し、手作業による工数を削減します。リモート接続時の「拒否」や「応答なし」による処理停止を防ぐ設計が実務上の鍵となります。
【処理フロー図】
graph TD
A["開始"] --> B["対象PC名リストの読み込み"]
B --> C["WMI接続試行"]
C --> D{"接続成功?"}
D -- Yes --> E["Win32クラスから情報抽出"]
D -- No --> F["エラー内容を記録"]
E --> G["配列へデータ格納"]
G --> H["全PC終了まで反復"]
H --> I["Excelシートへ一括出力"]
I --> J["終了"]
【実装:VBAコード】
参照設定を不要にする「レイトバインディング(遅延結合)」を採用し、配布しやすい構成にしています。
Option Explicit
' Win32 API宣言(64bit環境対応)
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' 高速化設定
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim i As Long
Dim strComputer As String
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim results() As Variant
ReDim results(1 To lastRow - 1, 1 To 4) ' PC名, OS, CPU, Memory
On Error Resume Next
For i = 2 To lastRow
strComputer = ws.Cells(i, 1).Value
results(i - 1, 1) = strComputer
If strComputer <> "" Then
' WMIサービスへの接続(タイムアウト考慮なしの標準接続)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If Err.Number = 0 Then
' --- OS情報の取得 ---
Set colItems = objWMIService.ExecQuery("Select Caption from Win32_OperatingSystem")
For Each objItem In colItems
results(i - 1, 2) = objItem.Caption
Next
' --- CPU情報の取得 ---
Set colItems = objWMIService.ExecQuery("Select Name from Win32_Processor")
For Each objItem In colItems
results(i - 1, 3) = objItem.Name
Next
' --- メモリ情報の取得 (単位: GB) ---
Set colItems = objWMIService.ExecQuery("Select TotalPhysicalMemory from Win32_ComputerSystem")
For Each objItem In colItems
results(i - 1, 4) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
Else
' 接続エラー時の処理
results(i - 1, 2) = "接続エラー: " & Err.Description
Err.Clear
End If
End If
' オブジェクトの解放
Set objWMIService = Nothing
Set colItems = Nothing
Next i
' 結果を一括出力
ws.Range("B2").Resize(UBound(results, 1), UBound(results, 2)).Value = results
' 設定の復元
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
On Error GoTo 0
MsgBox "情報取得が完了しました。", vbInformation
End Sub
【技術解説】
WMI (Windows Management Instrumentation): Windows OSを管理するためのインターフェースです。winmgmts: モニカーを使用してリモート名前空間にアクセスします。
遅延結合 (Late Binding): CreateObject や GetObject を使用することで、実行環境に依存せず、特定のライブラリ(Microsoft WMI Scripting V1.2 Library等)への参照設定が不要になります。
Win32クラスの選定:
Win32_OperatingSystem: OSのバージョンやエディション。
Win32_Processor: CPUの名称やコア数。
Win32_ComputerSystem: 合計物理メモリ。
配列処理の最適化: セルへの書き込みをループ内で行わず、一度配列に格納してから一括出力することで、通信負荷と描画負荷を最小限に抑えています。
【注意点と運用】
ファイアウォールの遮断: リモートPC側で「Windows Management Instrumentation (WMI)」の通信が許可されていない場合、接続エラーとなります。GPO(グループポリシー)等での事前設定が推奨されます。
実行権限: リモート接続には、対象PCに対する「管理者権限」を持つユーザーでVBA(Excel)を実行している必要があります。
タイムアウトの課題: GetObject はネットワーク接続不能なPCに対して数十秒フリーズする場合があります。大量のリストを処理する際は、事前に Ping 関数(Win32 API)で生存確認を行うロジックの追加を検討してください。
【まとめ】
疎通確認が先決: WMI接続前にPingで対象の生存を確認し、無駄な待機時間を削減する。
権限管理の徹底: 実行ユーザーが管理共有(C$等)にアクセスできる権限を有しているか確認する。
エラーハンドリング: 接続不可・情報欠落を想定し、On Error Resume Next を適切に制御してログを残す。
ライセンス:本記事のテキスト/コードは特記なき限り
CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。
コメント