1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PowerShellでバッテリ残量を取得して、閾値未満で且つユーザー応答が無ければOSをスリープ状態へ移行する

Posted at

概要

本リポジトリは、次の目的を達成する方法を説明します。

  • WindowsモバイルノートPCをバッテリー駆動で利用中に寝落ちした場合、自動的にスリープ状態に移行する

実現に使うツールは以下とします。いずれもWindowsに標準搭載されています。

  • タスクスケジューラ
  • PowerShell

実現だけすればよい場合は、前半のスクリプトの解説を飛ばして、後半の「タスクスケジューラへの設定方法」の節を参照ください。

検証環境

「Windows 10 Home」とします。

実現方法

次のようにして実現します。

  1. タスクスケジューラで定期的に、監視用のPowerShellスクリプトを起動
  2. PowerShellスクリプトでバッテリ残量を取得し(監視し)、閾値以下なら「作業を継続するか?」のダイアログを表示
  3. ダイアログは一定時間で自動クローズする設定とし、応答無しだった場合は「寝落ちしている」と判断してOSをスリープ状態へ移行

監視用スクリプトの作成

PowerShellでバッテリー残量を取得するには、WMIが提供するWin32_Batteryクラスを利用して、次のようにします(残量以外にも様々なバッテリー状態を取得できます)。
ここでは、後で表示に使うので「使用可能な残り時間」も合わせて取得しておきます。

Get-CimInstance -ClassName Win32_Battery | Select-Object -Property DeviceID, EstimatedChargeRemaining, EstimatedRunTime | Foreach-Object {
  # $DeviceID = $_.DeviceID

  # 残バッテリ量(100-0%) 
  $EstimatedChargeRemaining = $_.EstimatedChargeRemaining

  # 使用可能な残り時間(分)
  $EstimatedRunTime = $_.EstimatedRunTime
}

一定の表示時間で自動的に閉じるダイアログをPowerShellで表示するには、次のようにします。
ここではWscriptのポップアップを利用する方法とし、「はい」「いいえ」を表示するようにvbYesNoe (=4) を指定します。

  $wsobj = new-object -comobject wscript.shell
  $msgText = "表示するメッセージ"
  $nSecondsToWait = 5 # 表示する秒数
  $titleText = "タイトル文字列"

  $result = $wsobj.popup($msgText, $nSecondsToWait, $titleText, "4")

OSをスリープ状態へ移行するには、.Net FrameworkのSetSuspendState()を利用して、次のようにします。

Add-Type -Assembly System.Windows.Forms;[System.Windows.Forms.Application]::SetSuspendState(‘Suspend’, $false, $false);

以上の内容を用いて作成した、監視用のPowerShellスクリプトのサンプルは
message-sleep-battery.ps1 のようになります。
以降は、こちらのスクリプトを用いるものとして説明します。

タスクスケジューラへの設定方法

タスクスケジューラを起動して、次のようにタスクを設定します。
なお、手順中のスクリプトファイルは、任意のローカルの場所に格納した前提とします。

  1. 「タスクの作成」を選択
  2. タブ「全般」の「名前」に任意(例:message-battery-sleep等)の名称を入力
    • 他の項目はデフォルトのまま
    • img1-common.png
  3. タブ「トリガー」で「新規」ボタンを押します
  4. 「新しいトリガー」ダイアログで「繰り返し間隔:30分間」と「継続時間:無期限」を設定して「OK」ボタンを押します
    • img2-trigger.png
  5. タブ「操作」で「新規」ボタンを押します
  6. 「プログラム/スクリプト」に、PowerShellスクリプト、、、を起動するためのvbsスクリプトのパスを指定します
    • 直接PowerShell.exeを用いてスクリプトを実行しようとすると、「-WindowStyle Hidden」を指定しても、「スクリプトをウィンドウ非表示で起動する、ためのPowerShellウィンドウ」が表示されてしまうため、代わりにvbsを経由することで、ウィンドウが表示されることを防ぎます
    • vbsスクリプトは message-sleep-battery-wrapper.vbs のようにします
  7. 「引数の追加(オプション)」に、先に示した監視用のPowerShellスクリプト「message-sleep-battery.ps1」へのパスを入力します * img3-command.png
  8. タブ「条件」で「コンピューターをAC電源で試用している場合のみタスクを開始する」のチェックを外します
    • img4-conditions.png
  9. 「タスクの作成」ダイアログの右下にある「OK」ボタンを押してタスクを保存します

動作確認は、作成したタスクを選んで「実行」を押すことできます(スクリプト中の「 Set-Variable -Name THRESHOLD_BATTERY_CHARGE_REMAINING -Value 30 -Option Constant 」に指定したバッテリー残量を上回っている場合は、何も表示されません)。

以上で、監視タスクの定期実行のための設定は、完了です。

30分おきに監視用のスクリプトが動作し、バッテリーの残量が閾値未満の場合(この例であれば「30%」未満の場合)に、利用者が寝落ちしていないか?を確認するダイアログが表示され、応答が無ければOSをスリープ状態へ移行します。

(補足)この方法を選んだ背景

「寝落ちした場合に、自動的にスリープ状態へ移行して欲しい」を実現しようと考えた場合に、OS標準の「バッテリーの設定>電源とスリープ>次の時間が経過後、PCをスリープ状態にする」の設定で対応可能な場合が多いです。

しかし、上記の設定では「ブラウザゲームを表示中」や「Youtubeを再生中」における「寝落ち」への対処が出来ません(スリープ状態へ移行しません)。

なので、上記以外の方法でスリープ状態へ持って行く必要があります。

最初に検討したのはChrome拡張機能「The Marvellous Suspender」で、一定時間の操作が無い場合にChromeブラウザをスリープさせてしまえば「アイドル状態」になるのでは?というアプローチでした。
しかし、残念ながら「The Marvellous Suspender」は「アクティブでは無いタブをスリープさせる」ための拡張機能なので、今回の目的には沿いませんでした(アクティブなタブは、表示状態のままとなります)。

次に、タスクスケジューラの「トリガー」にある「アイドル状態の時」を利用する方法を
検討しましたが、これも期待した動作を実現できませんでした。「ゲームや動画を再生中」は、たとえ一定時間ユーザー入力が無くとも「Notアイドル状態」と判定されるようです。

バッテリー監視系のソフトで、そのような機能を有するものが無いかを検索したところ、
「バッテリー状態をトリガーとしてタスクを実行する」機能を有するソフトはありました。
しかし、そのソフトにとって「トリガー」はあくまでサブの機能であり、今回の目的のためだけに追加ソフト導入するのは、出来れば見送りたい、と考えたため、こちらは保留としました。

ならば、ということで、「バッテリー状態を監視して条件を満たしたら、スリープさせる
アプリ」をいっそのこと作ってしまえば、、、とも考えましたが、ソコまで労力をかけるのは出来れば見送りたい、と考えて保留としました。

以上を踏まえて、「(このくらいの機能なら)スクリプトとタスクスケジューラを組み合わせて何とか実現できないか?」と考えた結果に、今回の実現方法に辿り着いた、というのが背景と成ります。

なお、タスクスケジューラから実行時に、ウィンドウを非表示にするにはvbs経由とする
必要があるので、スクリプト自体をvbsで書くことも考えましたが(とりあえずは作成済み)、OSをスリープ状態にするにはPowerShellが最適である、と言う背景から、スクリプト本体はPowerShellとする、という判断を最終的にはしました。

PowerShell(だけでなくvbsも)は、今回に初めて書いたので、「xxと書いた方がより適切」などの指摘があれば、コメントいただけると助かります。また、「そもそも、○○と言う方法で、もっと簡単に実現できる」なども歓迎します。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?