<p><style_prompt>
【執筆作法】</style_prompt></p>
<ol class="wp-block-list">
<li><p>専門用語を平易な語彙で補足し、技術的解像度と読みやすさを両立させる。</p></li>
<li><p>「なぜそのコードが必要か」という設計意図(Design Intent)を明文化する。</p></li>
<li><p>リスク管理(例外処理)を実装レベルで提案する。
</p></li>
</ol>
<p>本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">VBA×WMIによるリモートPC資産管理:OS・CPU・メモリ情報の自動取得の実践</h1>
<h3 class="wp-block-heading">【背景と目的】</h3>
<p>IT資産管理において、数百台の端末情報を手動で確認するのは非効率です。本ツールは、WMIを用いてリモートPCのスペック情報を一括収集し、管理工数を削減します。
実務では「リモート接続時のタイムアウトによるフリーズ」や「権限不足による実行エラー」が大きな壁となりますが、本ガイドではエラーハンドリングを組み込んだ堅牢なコードを提示します。</p>
<h3 class="wp-block-heading">【処理フロー図】</h3>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["開始"] --> B["対象ホスト名/IPの読み込み"]
B --> C["SWbemLocatorによるリモート接続試行"]
C -->|成功| D["WMIクエリ実行: OS/CPU/Memory"]
C -->|失敗| E["エラー内容をシートへ記録"]
D --> F["取得データを配列へ格納"]
F --> G["シートへ一括書き出し"]
G --> H["終了"]
</pre></div>
<h3 class="wp-block-heading">【実装:VBAコード】</h3>
<p>参照設定(Microsoft WMI Scripting v1.2 Library)を不要にする「実行時バインド(Late Binding)」方式を採用しています。</p>
<pre data-enlighter-language="generic">Option Explicit
' Win32 API宣言(64bit/32bit両対応)
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' 高速化設定
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Dim i As Long
Dim targetPC As String
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim results() As Variant
ReDim results(1 To 1, 1 To 4) ' OS, CPU, RAM, Status
' A列にホスト名が入っている想定(2行目から開始)
For i = 2 To lastRow
targetPC = ws.Cells(i, 1).Value
On Error Resume Next
' WMI接続オブジェクトの作成
' タイムアウト対策として、接続試行前にPing確認を行うのが理想的(今回はWMI接続で判定)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & targetPC & "\root\cimv2")
If Err.Number <> 0 Then
ws.Cells(i, 5).Value = "Error: " & Err.Description
Err.Clear
Else
' 1. OS情報の取得
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
For Each objItem In colItems
results(1, 1) = objItem.Caption & " (" & objItem.OSArchitecture & ")"
results(1, 3) = Round(objItem.TotalVisibleMemorySize / 1024 / 1024, 1) & " GB"
Next
' 2. CPU情報の取得
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
For Each objItem In colItems
results(1, 2) = Trim(objItem.Name)
Next
results(1, 4) = "Success"
' 配列からシートへ一括書き出し(セルへの個別アクセスを低減)
ws.Cells(i, 2).Resize(1, 4).Value = results
End If
' オブジェクトの解放
Set objWMIService = Nothing
Set colItems = Nothing
DoEvents ' OSに制御を戻しフリーズを防止
Next i
' 設定の復元
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
MsgBox "システム情報の取得が完了しました。", vbInformation
End Sub
</pre>
<h3 class="wp-block-heading">【技術解説】</h3>
<ol class="wp-block-list">
<li><p><strong>WMI (Windows Management Instrumentation)</strong>:
Windowsの管理情報を取得するための標準インターフェースです。<code>root\cimv2</code> 名前空間には、ハードウェアに関するほぼすべてのクラス(Win32_Processor等)が含まれています。</p></li>
<li><p><strong>実行時バインド (Late Binding)</strong>:
<code>CreateObject</code> や <code>GetObject</code> を使用することで、配布先PCでの「参照設定エラー」を回避します。</p></li>
<li><p><strong>配列処理による高速化</strong>:
1セルずつ書き込むのではなく、<code>Resize</code> プロパティを用いて配列を一度に流し込むことで、Excelの描画回数を最小限に抑えています。</p></li>
<li><p><strong>PtrSafe 宣言</strong>:
64bit版OfficeではAPI宣言に <code>PtrSafe</code> が必須です。これを怠ると実行時エラーでVBAが停止します。</p></li>
</ol>
<h3 class="wp-block-heading">【注意点と運用】</h3>
<ul class="wp-block-list">
<li><p><strong>ファイアウォールの許可</strong>: リモートPC側で「WMI (RPC)」の通信が許可されている必要があります。企業環境ではグループポリシー(GPO)での設定確認が必須です。</p></li>
<li><p><strong>実行権限</strong>: リモートPCに対して管理者権限を持つユーザーでExcelを実行する必要があります。</p></li>
<li><p><strong>タイムアウトの罠</strong>: 存在しないPCや電源オフのPCに対して <code>GetObject</code> を行うと、数秒〜数十秒の応答待ち(ハングアップ状態)が発生します。事前に <code>WMI</code> 接続前に <code>Ping</code> による死活監視を挟む設計がより実用的です。</p></li>
</ul>
<h3 class="wp-block-heading">【まとめ】</h3>
<ol class="wp-block-list">
<li><p><strong>WMIは標準機能のみで動作する</strong>ため、追加インストールの必要がない強力な資産管理ツールになる。</p></li>
<li><p><strong>エラーハンドリングとDoEvents</strong>を組み合わせることで、大量のリスト処理でもExcelをクラッシュさせずに実行できる。</p></li>
<li><p><strong>ネットワーク環境(権限・FW)の事前確認</strong>が、コードそのものよりも重要になる。</p></li>
</ol>
【執筆作法】
専門用語を平易な語彙で補足し、技術的解像度と読みやすさを両立させる。
「なぜそのコードが必要か」という設計意図(Design Intent)を明文化する。
リスク管理(例外処理)を実装レベルで提案する。
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBA×WMIによるリモートPC資産管理:OS・CPU・メモリ情報の自動取得の実践
【背景と目的】
IT資産管理において、数百台の端末情報を手動で確認するのは非効率です。本ツールは、WMIを用いてリモートPCのスペック情報を一括収集し、管理工数を削減します。
実務では「リモート接続時のタイムアウトによるフリーズ」や「権限不足による実行エラー」が大きな壁となりますが、本ガイドではエラーハンドリングを組み込んだ堅牢なコードを提示します。
【処理フロー図】
graph TD
A["開始"] --> B["対象ホスト名/IPの読み込み"]
B --> C["SWbemLocatorによるリモート接続試行"]
C -->|成功| D["WMIクエリ実行: OS/CPU/Memory"]
C -->|失敗| E["エラー内容をシートへ記録"]
D --> F["取得データを配列へ格納"]
F --> G["シートへ一括書き出し"]
G --> H["終了"]
【実装:VBAコード】
参照設定(Microsoft WMI Scripting v1.2 Library)を不要にする「実行時バインド(Late Binding)」方式を採用しています。
Option Explicit
' Win32 API宣言(64bit/32bit両対応)
#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(1)
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' 高速化設定
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Dim i As Long
Dim targetPC As String
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim results() As Variant
ReDim results(1 To 1, 1 To 4) ' OS, CPU, RAM, Status
' A列にホスト名が入っている想定(2行目から開始)
For i = 2 To lastRow
targetPC = ws.Cells(i, 1).Value
On Error Resume Next
' WMI接続オブジェクトの作成
' タイムアウト対策として、接続試行前にPing確認を行うのが理想的(今回はWMI接続で判定)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & targetPC & "\root\cimv2")
If Err.Number <> 0 Then
ws.Cells(i, 5).Value = "Error: " & Err.Description
Err.Clear
Else
' 1. OS情報の取得
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
For Each objItem In colItems
results(1, 1) = objItem.Caption & " (" & objItem.OSArchitecture & ")"
results(1, 3) = Round(objItem.TotalVisibleMemorySize / 1024 / 1024, 1) & " GB"
Next
' 2. CPU情報の取得
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")
For Each objItem In colItems
results(1, 2) = Trim(objItem.Name)
Next
results(1, 4) = "Success"
' 配列からシートへ一括書き出し(セルへの個別アクセスを低減)
ws.Cells(i, 2).Resize(1, 4).Value = results
End If
' オブジェクトの解放
Set objWMIService = Nothing
Set colItems = Nothing
DoEvents ' OSに制御を戻しフリーズを防止
Next i
' 設定の復元
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
MsgBox "システム情報の取得が完了しました。", vbInformation
End Sub
【技術解説】
WMI (Windows Management Instrumentation):
Windowsの管理情報を取得するための標準インターフェースです。root\cimv2 名前空間には、ハードウェアに関するほぼすべてのクラス(Win32_Processor等)が含まれています。
実行時バインド (Late Binding):
CreateObject や GetObject を使用することで、配布先PCでの「参照設定エラー」を回避します。
配列処理による高速化:
1セルずつ書き込むのではなく、Resize プロパティを用いて配列を一度に流し込むことで、Excelの描画回数を最小限に抑えています。
PtrSafe 宣言:
64bit版OfficeではAPI宣言に PtrSafe が必須です。これを怠ると実行時エラーでVBAが停止します。
【注意点と運用】
ファイアウォールの許可: リモートPC側で「WMI (RPC)」の通信が許可されている必要があります。企業環境ではグループポリシー(GPO)での設定確認が必須です。
実行権限: リモートPCに対して管理者権限を持つユーザーでExcelを実行する必要があります。
タイムアウトの罠: 存在しないPCや電源オフのPCに対して GetObject を行うと、数秒〜数十秒の応答待ち(ハングアップ状態)が発生します。事前に WMI 接続前に Ping による死活監視を挟む設計がより実用的です。
【まとめ】
WMIは標準機能のみで動作するため、追加インストールの必要がない強力な資産管理ツールになる。
エラーハンドリングとDoEventsを組み合わせることで、大量のリスト処理でもExcelをクラッシュさせずに実行できる。
ネットワーク環境(権限・FW)の事前確認が、コードそのものよりも重要になる。
コメント