<p><!-- [STYLE_PROMPT_VERSION: 1.2] [TONE: PROFESSIONAL_PRACTICAL] [LOCALE: JP] -->
本記事は<strong>Geminiの出力をプロンプト工学で整理した業務ドラフト(未検証)</strong>です。</p>
<h1 class="wp-block-heading">VBAとWMIで実現する「リモートPC情報一括取得システム」の構築</h1>
<h3 class="wp-block-heading">【背景と目的】</h3>
<p>IT資産管理や保守にて、複数端末の情報を手動収集する負荷を解消。VBAとWMIで、OS・CPU・メモリ情報を一括取得・自動集計する仕組みを提案します。</p>
<h3 class="wp-block-heading">【処理フロー図】</h3>
<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">
graph TD
A["開始"] --> B["ターゲットPCリスト読み込み"]
B --> C["リモートWMI接続試行"]
C -->|成功| D["OS/CPU/RAM情報をクエリ"]
C -->|失敗| E["エラー内容をログ出力"]
D --> F["配列に結果を格納"]
F --> G["ワークシートへ一括書き出し"]
G --> H["終了"]
</pre></div>
<h3 class="wp-block-heading">【実装:VBAコード】</h3>
<pre data-enlighter-language="generic">Option Explicit
' Win32 APIを使用する場合のPtrSafe宣言(本コードではWMIをLate Bindingで使用)
#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
''' <summary>
''' リモートPCの情報を取得し、アクティブシートに出力する
''' </summary>
Public Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' 処理高速化の設定
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Dim pcName As String
Dim i As Long
Dim results() As Variant
ReDim results(1 To lastRow - 1, 1 To 4) ' OS, CPU, RAM, Status
On Error Resume Next
For i = 2 To lastRow
pcName = ws.Cells(i, 1).Value
If pcName <> "" Then
' 情報取得処理
Call FetchWmiData(pcName, results, i - 1)
End If
Next i
' シートへ一括出力(セルへの個別書き込みを避けて高速化)
ws.Range("B2").Resize(UBound(results, 1), 4).Value = results
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
MsgBox "情報取得が完了しました。", vbInformation
End Sub
''' <summary>
''' WMIクエリを実行してシステム情報を配列に格納
''' </summary>
Private Sub FetchWmiData(ByVal pcName As String, ByRef results() As Variant, ByVal idx As Long)
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim connectionPath As String
' リモート接続パスの構築(名前解決ができる前提)
connectionPath = "winmgmts:{impersonationLevel=impersonate}!\\" & pcName & "\root\cimv2"
Set objWMIService = GetObject(connectionPath)
If Err.Number <> 0 Then
results(idx, 4) = "接続エラー: " & Err.Description
Err.Clear
Exit Sub
End If
' 1. OS情報の取得
Set colItems = objWMIService.ExecQuery("Select Caption From Win32_OperatingSystem")
For Each objItem In colItems
results(idx, 1) = objItem.Caption
Next
' 2. CPU情報の取得
Set colItems = objWMIService.ExecQuery("Select Name From Win32_Processor")
For Each objItem In colItems
results(idx, 2) = objItem.Name
Next
' 3. メモリ情報の取得 (単位: GBに変換)
Set colItems = objWMIService.ExecQuery("Select TotalPhysicalMemory From Win32_ComputerSystem")
For Each objItem In colItems
results(idx, 3) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
results(idx, 4) = "成功"
End Sub
</pre>
<h3 class="wp-block-heading">【技術解説】</h3>
<ol class="wp-block-list">
<li><p><strong>Late Binding (遅延結合)</strong>: 参照設定(Microsoft WMI Scripting Library)を不要にするため、<code>CreateObject</code>や<code>GetObject</code>を使用。配布時の環境差異による「参照不可」エラーを防止します。</p></li>
<li><p><strong>WQL (WMI Query Language)</strong>: <code>Select * From...</code> 形式でSQLのようにOS内部情報を取得。<code>Win32_OperatingSystem</code>(OS名)、<code>Win32_Processor</code>(CPU名)、<code>Win32_ComputerSystem</code>(物理メモリ)を利用しています。</p></li>
<li><p><strong>高速化ロジック</strong>: セルへの書き込みをループ内で行わず、一度配列(<code>results</code>)に格納してから <code>Resize</code> メソッドで一括出力。100台規模の処理でもオーバーヘッドを最小化します。</p></li>
</ol>
<h3 class="wp-block-heading">【注意点と運用】</h3>
<ul class="wp-block-list">
<li><p><strong>管理者権限とファイアウォール</strong>: リモートPC側で「WMIの許可」および「RPC通信(TCP 135番等)」が許可されている必要があります。ドメイン環境でない場合、接続が拒否されるケースが多いです。</p></li>
<li><p><strong>タイムアウト</strong>: 存在しないPC名やオフラインの端末に対しては、<code>GetObject</code> で数十秒フリーズする場合があります。事前に <code>Ping</code> コマンド等で死活確認を行うロジックの追加を推奨します。</p></li>
<li><p><strong>UACの影響</strong>: ローカル管理者権限を持つユーザーでExcelを実行する必要があります。</p></li>
</ul>
<h3 class="wp-block-heading">【まとめ】</h3>
<ul class="wp-block-list">
<li><p><strong>権限の確認</strong>: 実行ユーザーが対象PCの管理者権限を持っていることが大前提です。</p></li>
<li><p><strong>配列の活用</strong>: セル操作を最小限に抑えることで、大量端末の処理速度を劇的に向上させます。</p></li>
<li><p><strong>エラー処理の徹底</strong>: 接続失敗を想定し、<code>On Error Resume Next</code> とステータスログ出力をセットで運用しましょう。</p></li>
</ul>
本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
VBAとWMIで実現する「リモートPC情報一括取得システム」の構築
【背景と目的】
IT資産管理や保守にて、複数端末の情報を手動収集する負荷を解消。VBAとWMIで、OS・CPU・メモリ情報を一括取得・自動集計する仕組みを提案します。
【処理フロー図】
graph TD
A["開始"] --> B["ターゲットPCリスト読み込み"]
B --> C["リモートWMI接続試行"]
C -->|成功| D["OS/CPU/RAM情報をクエリ"]
C -->|失敗| E["エラー内容をログ出力"]
D --> F["配列に結果を格納"]
F --> G["ワークシートへ一括書き出し"]
G --> H["終了"]
【実装:VBAコード】
Option Explicit
' Win32 APIを使用する場合のPtrSafe宣言(本コードではWMIをLate Bindingで使用)
#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
''' <summary>
''' リモートPCの情報を取得し、アクティブシートに出力する
''' </summary>
Public Sub GetRemoteSystemInfo()
Dim ws As Worksheet
Set ws = ThisWorkbook.ActiveSheet
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
' 処理高速化の設定
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Dim pcName As String
Dim i As Long
Dim results() As Variant
ReDim results(1 To lastRow - 1, 1 To 4) ' OS, CPU, RAM, Status
On Error Resume Next
For i = 2 To lastRow
pcName = ws.Cells(i, 1).Value
If pcName <> "" Then
' 情報取得処理
Call FetchWmiData(pcName, results, i - 1)
End If
Next i
' シートへ一括出力(セルへの個別書き込みを避けて高速化)
ws.Range("B2").Resize(UBound(results, 1), 4).Value = results
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
MsgBox "情報取得が完了しました。", vbInformation
End Sub
''' <summary>
''' WMIクエリを実行してシステム情報を配列に格納
''' </summary>
Private Sub FetchWmiData(ByVal pcName As String, ByRef results() As Variant, ByVal idx As Long)
Dim objWMIService As Object
Dim colItems As Object
Dim objItem As Object
Dim connectionPath As String
' リモート接続パスの構築(名前解決ができる前提)
connectionPath = "winmgmts:{impersonationLevel=impersonate}!\\" & pcName & "\root\cimv2"
Set objWMIService = GetObject(connectionPath)
If Err.Number <> 0 Then
results(idx, 4) = "接続エラー: " & Err.Description
Err.Clear
Exit Sub
End If
' 1. OS情報の取得
Set colItems = objWMIService.ExecQuery("Select Caption From Win32_OperatingSystem")
For Each objItem In colItems
results(idx, 1) = objItem.Caption
Next
' 2. CPU情報の取得
Set colItems = objWMIService.ExecQuery("Select Name From Win32_Processor")
For Each objItem In colItems
results(idx, 2) = objItem.Name
Next
' 3. メモリ情報の取得 (単位: GBに変換)
Set colItems = objWMIService.ExecQuery("Select TotalPhysicalMemory From Win32_ComputerSystem")
For Each objItem In colItems
results(idx, 3) = Round(objItem.TotalPhysicalMemory / 1024 / 1024 / 1024, 2) & " GB"
Next
results(idx, 4) = "成功"
End Sub
【技術解説】
Late Binding (遅延結合): 参照設定(Microsoft WMI Scripting Library)を不要にするため、CreateObjectやGetObjectを使用。配布時の環境差異による「参照不可」エラーを防止します。
WQL (WMI Query Language): Select * From... 形式でSQLのようにOS内部情報を取得。Win32_OperatingSystem(OS名)、Win32_Processor(CPU名)、Win32_ComputerSystem(物理メモリ)を利用しています。
高速化ロジック: セルへの書き込みをループ内で行わず、一度配列(results)に格納してから Resize メソッドで一括出力。100台規模の処理でもオーバーヘッドを最小化します。
【注意点と運用】
管理者権限とファイアウォール: リモートPC側で「WMIの許可」および「RPC通信(TCP 135番等)」が許可されている必要があります。ドメイン環境でない場合、接続が拒否されるケースが多いです。
タイムアウト: 存在しないPC名やオフラインの端末に対しては、GetObject で数十秒フリーズする場合があります。事前に Ping コマンド等で死活確認を行うロジックの追加を推奨します。
UACの影響: ローカル管理者権限を持つユーザーでExcelを実行する必要があります。
【まとめ】
権限の確認: 実行ユーザーが対象PCの管理者権限を持っていることが大前提です。
配列の活用: セル操作を最小限に抑えることで、大量端末の処理速度を劇的に向上させます。
エラー処理の徹底: 接続失敗を想定し、On Error Resume Next とステータスログ出力をセットで運用しましょう。
コメント