PowerShellでWindowsの最後の起動時刻を確認する標準的な方法は、Get-CimInstance Win32_OperatingSystemのLastBootUpTimeを読むことです。PowerShell 6以降ならGet-Uptime -Sinceでも起動時刻を取得できます。ただし、最後にユーザーがサインインした時刻、電源ボタンを押した時刻、スリープから復帰した時刻、更新が完了した時刻とは別です。高速スタートアップ、仮想マシンの保存・復元、時計同期も解釈へ影響します。本記事では複数の読み取り方法を照合し、再起動の有無を安全に判断する手順を解説します。
まず「起動時刻」として知りたい事象を決める
障害調査で知りたいのが、OSカーネルが起動した時刻、最後のユーザーサインイン、スリープ復帰、更新後の再起動、サービスの再起動、仮想マシンの復元のどれかを明確にします。LastBootUpTimeはWindows OSの起動時刻を示すプロパティで、利用者のログオン時刻ではありません。サービスやアプリだけが再起動しても通常は変わりません。
問い合わせには現在時刻、タイムゾーン、端末名、期待した再起動操作、取得結果をセットで残します。「昨日シャットダウンした」という利用者の記憶と値が違う場合も、すぐに異常と決めません。高速スタートアップ、休止、スリープ、仮想化、端末管理の電源操作、時計のずれを確認します。再起動の証明には起動時刻だけでなくイベントログや更新履歴を合わせます。
Win32_OperatingSystemのLastBootUpTimeを取得する
Get-CimInstance -ClassName Win32_OperatingSystemは現在のWindows OSを表すCIMインスタンスを返します。LastBootUpTimeだけを選ぶと、PowerShellでは通常DateTimeとして扱える値を確認できます。Caption、Version、BuildNumber、CSNameも同時に残すと、別端末やOSビルドの結果を取り違えにくくなります。
Get-CimInstance -ClassName Win32_OperatingSystem |
Select-Object CSName, Caption, Version, BuildNumber, LastBootUpTime
WMIの古い例で使われるGet-WmiObjectより、現在のスクリプトではCIMコマンドを入口にします。LastBootUpTimeがDateTimeで返るかは使用環境で確認し、文字列のまま並べ替えません。リモート端末ではCimSessionを使えますが、接続失敗、権限不足、タイムアウトを「起動時刻不明」または「端末停止」と明確に分けます。資格情報を平文で保存しません。
現在時刻との差から稼働時間を計算する
Win32_OperatingSystemから得たLastBootUpTimeを現在のGet-Dateから引くと、TimeSpanとして経過時間を確認できます。起動時刻と現在時刻を同じ端末上で取得し、計算した時刻も記録します。TimeSpanのTotalDaysは小数を含む総日数、Daysは日部分なので、報告ではどちらを使ったかを明記します。
$os = Get-CimInstance Win32_OperatingSystem
$now = Get-Date
[pscustomobject]@{
ComputerName = $os.CSName
CheckedAt = $now
LastBoot = $os.LastBootUpTime
Uptime = $now - $os.LastBootUpTime
}
この差分は壁時計に基づくため、起動後に日時やタイムゾーンが大きく変更された場合、期待と違う値になる可能性があります。負の値や異常に長い値なら、NTP同期、手動変更、仮想マシンの時刻、CIM値の型、取得元端末を確認します。監視でしきい値判定する場合は、取得失敗を0日として扱わず、Unknownにします。小さな差は取得タイミングによるものとして許容します。
PowerShell 6以降ではGet-Uptimeを使える
Get-UptimeはPowerShell 6.0で導入され、既定では最後の起動からのTimeSpan、-Sinceでは起動時刻のDateTimeを返します。PowerShell 7が利用できる端末では簡潔です。Windows PowerShell 5.1には標準で存在しないため、コマンドが見つからないことをOSの問題とせず、$PSVersionTable.PSVersionで実行エンジンの版を確認します。
Get-Uptime
Get-Uptime -Since
$PSVersionTable.PSVersion
Microsoftの資料では、Get-Uptimeは高解像度タイマーを使い、Win32_OperatingSystem.LastBootUpTimeとの差分から求める方法と少し異なる可能性があると説明されています。秒単位のわずかな差を障害としません。複数端末を比較する場合は同じ方法とPowerShell版へそろえ、起動時刻、稼働時間、取得時刻のどれを保存したかを列名で明確にします。
高速スタートアップと再起動を区別する
Windowsの高速スタートアップが有効な環境では、通常のシャットダウンがカーネルセッションを休止して次回起動時に復元する方式になることがあります。そのため、利用者が電源を切ったつもりでも、LastBootUpTimeや稼働時間が期待どおりリセットされない場合があります。一方、再起動は完全なブートを行うため、更新やドライバー適用の確認では「シャットダウンして電源投入」と「再起動」を区別します。
起動時刻を合わせるために高速スタートアップを無効化する必要はありません。電源ポリシーは起動時間、バッテリー、更新、暗号化、管理運用へ影響します。組織の設定を変更せず、まず利用者が実行した操作と取得値を記録し、必要なら承認された再起動を案内します。更新作業中や暗号化中の端末を無断で再起動するとデータ損失や復旧作業が生じるため、実行前に状態を確認します。
スリープ、休止、サインインはLastBootUpTimeを更新しない
スリープからの復帰は通常、新しいOSブートではないためLastBootUpTimeは変わりません。休止状態からの復元や高速スタートアップも、利用者の体感では電源を入れ直したように見えても、完全再起動とは異なる場合があります。ロック解除やサインアウト・サインイン、ユーザー切替もOSの起動時刻を更新しません。障害がサインイン後だけ起きるなら、ユーザーセッションの開始時刻を別に調べます。
アプリの「起動時刻」を知りたい場合は、そのプロセスのStartTimeやサービス状態を確認します。ネットワーク切断の契機がスリープ復帰ならPower-TroubleshooterやKernel-Power関連イベント、デバイスログを時刻で照合します。一つのLastBootUpTimeを、電源イベント、ユーザーイベント、サービスイベントの代用にしないことが重要です。調査対象ごとに適切なログを選びます。
イベントログで起動と停止の時系列を照合する
Get-WinEventでSystemログを時間範囲へ絞ると、起動、シャットダウン、予期しない停止、電源復帰、更新に関係するイベントを確認できます。EventLog、Kernel-Boot、Kernel-General、Kernel-Powerなどのプロバイダーが手掛かりになりますが、イベントIDの意味はWindows版とプロバイダーを合わせて確認します。単一の番号だけを全環境の起動証拠にしません。
Get-WinEvent -FilterHashtable @{
LogName = "System"
StartTime = (Get-Date).AddDays(-7)
} -MaxEvents 200 |
Where-Object ProviderName -match "Kernel|EventLog" |
Select-Object TimeCreated, ProviderName, Id, LevelDisplayName, Message
ログ保持期間より古い起動は残っていない可能性があり、ログ消去や転送設定でも見え方が変わります。メッセージには端末情報や障害情報が含まれるため、共有先を限定します。時系列ではLastBootUpTimeの前後に、正常な停止、予期しない停止、更新、時計変更があるかを見ます。ログを削除したり監査を無効化したりせず、必要なら承認された保管先へエクスポートします。
仮想マシンとクラウドPCではホスト操作を考慮する
仮想マシンの保存、チェックポイント復元、ライブマイグレーション、バックアップ復元、クラウドPCの再プロビジョニングでは、ゲストOSのLastBootUpTimeと利用者が接続し直した時刻が一致しない場合があります。ゲスト内の値だけで物理ホストの再起動を判断できません。ハイパーバイザーやクラウド管理画面の操作履歴、ゲストイベントを権限のある管理者が照合します。
チェックポイントへ戻すと、ゲスト内の時計やログも過去の状態へ戻る可能性があります。単調に増えると期待した監視値が逆行した場合は、時計同期だけでなく復元操作を確認します。利用者端末の時刻と管理画面のUTC表示を比較するときはタイムゾーンを明記します。仮想マシンを再起動して確認する前に、稼働中サービス、冗長化、スナップショット方針、利用者通知を確認します。
更新適用の確認は起動時刻だけで完結させない
LastBootUpTimeが更新インストール後なら「その後にOSが起動した」手掛かりになりますが、更新が成功し必要な再起動を完了したことを単独で保証しません。Windows Updateの履歴、OSビルド、対象KB、再起動保留状態、イベントログ、管理基盤の準拠状態を確認します。累積更新では適用対象や置き換え関係も考慮します。
逆に長時間稼働していても、すべての端末で直ちに強制再起動すべきとは限りません。サーバー、共有端末、仮想デスクトップ、更新リングごとにメンテナンス方針があります。稼働日数はリスク評価の一項目として報告し、再起動期限、利用者セッション、業務処理、フェールオーバー、バックアップ、回復キーを確認して計画します。確認スクリプトから自動再起動を呼び出しません。
確認結果を残すチェックリスト
- OS起動、サインイン、スリープ復帰、サービス再起動のどれを知りたいか決めたか
- Win32_OperatingSystemのLastBootUpTimeと取得時刻・タイムゾーンを残したか
- Get-UptimeがPowerShell 6以降であることを確認したか
- 高速スタートアップ、休止、スリープで値の解釈が変わる点を考慮したか
- イベントログで正常停止、予期しない停止、時計変更、更新を照合したか
- 仮想マシンの保存・復元とホスト操作をゲスト起動と混同していないか
- 起動時刻だけで更新完了やアプリ正常を断定していないか
結果は、取得日時とタイムゾーン、端末名、Windowsのエディションとビルド、PowerShellの版、実行ユーザー、取得方法を添えて保存します。値が空または取得失敗の場合は、対象が存在しないと断定せず、権限、モジュール、OS、接続状態、リモート管理経路を確認します。再起動、削除、最適化、修復、設定変更が必要になったら読み取り確認と分離し、利用者への影響、バックアップ、承認、戻し方を決めます。

コメント