【入門編】【稼働時間計測】WMI Win32_OperatingSystem の LastBootUpTime を用いたOS連続稼働時間(Uptime)算出 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

こんにちは。自動化の現場でVBScriptと長年戦ってきたエンジニアです。

皆さんは、運用監視の現場で「このサーバー、最後にいつ再起動されたんだろう?」と悩んだことはありませんか?GUIのタスクマネージャーを開くのも良いですが、自動化エンジニアとしては、「スクリプト一発で、OSの稼働時間を秒単位で弾き出す」という美学を追求したいところです。

今回は、WMI(Windows Management Instrumentation)というWindowsの心臓部に触れ、`LastBootUpTime` を料理する方法を伝授します。これさえマスターすれば、VBScriptの「日付データの不自由さ」を克服する力が身につきますよ。

1. WMIの「異質な時間形式」を解読せよ

Windows内部で使われているWMIの日付形式は、`CIM_DATETIME` と呼ばれる特殊な文字列です。例えば `20231027103000.000000+540` のような形式で返ってきます。

  • 2023(年)10(月)27(日)10(時)30(分)00(秒)…

人間には読めますが、VBScriptの計算エンジンである `Date` 型は、このままでは理解できません。我々の仕事は、この文字列を「切り刻んで」、`DateSerial` 関数などが扱える形式へ再構築することです。

2. 稼働時間算出のロジックを実装する

では、実際にOSの最終起動日時を取得し、現在時刻との差分(=稼働時間)を算出するスクリプトを見てみましょう。

‘ WMI経由でOS稼働時間を算出するスクリプト
Option Explicit

Dim objWMIService, objOS, colOS
Dim strBootDate, dtBootDate, dtNow, tsUptime

‘ 1. WMIサービスへ接続(ローカルホスト)
Set objWMIService = GetObject(“winmgmts:\\.\root\cimv2”)
Set colOS = objWMIService.ExecQuery(“Select from Win32_OperatingSystem”)

For Each objOS in colOS
‘ 2. CIM_DATETIME形式の文字列を取得 (例: 20231027…)
strBootDate = objOS.LastBootUpTime

‘ 3. 文字列を解析してDate型へ変換する関数を呼び出し
dtBootDate = WMIDateToDate(strBootDate)
dtNow = Now()

‘ 4. 差分計算(DateDiffで分単位を取得)
tsUptime = DateDiff(“n”, dtBootDate, dtNow)

WScript.Echo “最終起動日時: ” & dtBootDate
WScript.Echo “現在時刻 : ” & dtNow
WScript.Echo “連続稼働時間: ” & tsUptime & ” 分 (” & Round(tsUptime / 1440, 2) & ” 日)”
Next

‘ ———————————————————
‘ WMIの日付文字列をVBScript標準のDate型に変換する関数
‘ ———————————————————
Function WMIDateToDate(wmiDate)
Dim yyyy, mm, dd, hh, min, ss

‘ 文字列の特定位置をスライスして抽出
yyyy = Mid(wmiDate, 1, 4)
mm = Mid(wmiDate, 5, 2)
dd = Mid(wmiDate, 7, 2)
hh = Mid(wmiDate, 9, 2)
min = Mid(wmiDate, 11, 2)
ss = Mid(wmiDate, 13, 2)

‘ DateSerialでDate型へ構築
WMIDateToDate = DateSerial(yyyy, mm, dd) + TimeSerial(hh, min, ss)
End Function

3. このコードで押さえておくべき「3つのポイント」

① `Mid` 関数の活用

WMIの日付は桁数が固定されています。`Mid(str, start, length)` を使うことで、年・月・日を正確に切り出せます。これはVBScriptにおける文字列操作の基本中の基本です。

② `DateSerial` と `TimeSerial` の組み合わせ

日付データを作るときは、`DateSerial(年, 月, 日)` に `TimeSerial(時, 分, 秒)` を足し合わせるのが最も安全です。浮動小数点ベースで計算するよりも、直感的に日付オブジェクトを生成できます。

③ なぜ `DateDiff` を使うのか?

`Now – dtBootDate` と引き算をしてはいけません。VBScriptにおいて日付の引き算を行うと、結果は「日数」になりますが、時間や分単位で正確にハンドリングしたい場合は `DateDiff` 関数を使うのが「プロの作法」です。

初学者が陥りやすい罠:エラーハンドリングの重要性

現場でこのコードを使う際、「WMIが反応しない」というケースに遭遇することがあります。

  • 権限不足: WMIは管理者権限を要求するクエリが多いです。実行時は必ず「管理者として実行」を意識してください。
  • WMIリポジトリの破損: 滅多にありませんが、特定の環境では `GetObject` がタイムアウトします。`On Error Resume Next` を使い、`If Err.Number <> 0 Then` でエラーを拾う習慣をつけましょう。

最後に:自動化エンジニアの心構え

今回作成したスクリプトは、ただの「稼働時間計算機」ではありません。これは「システムの状態を可視化するセンサー」の第一歩です。

ここから、さらに「稼働時間が30日を超えていたらアラートメールを飛ばす」といった機能を追加すれば、立派な運用ツールになります。VBScriptは古い言語だと言われますが、WindowsというOSの深淵を覗くための最高のツールであることに変わりはありません。

ぜひ、このコードを自分の環境で動かし、改造してみてください。動いた時の小さな感動こそが、エンジニアとしての最大の報酬ですよ!

タイトルとURLをコピーしました