目次
PowerShellのSleepとは?
PowerShellはWindows10に標準で入っているシェル機能です。シェルとはウィンドウでコマンドを入力して様々な処理を行うための機能で、PowerShellはコマンドプロンプトのパワーアップ版といえるでしょう。
Sleepは一般的には指定された時間だけ何もせず待つ機能です。一見役に立たなさそうですが、シェルでは必要になるケースが多いのです。PowerShellにもこの機能があるので、解説します。またPowerShellでWindowsのシステム自体をSleepする方法も解説します。
Start-Sleepでスリープができる
PowerShellでSleepするには、以下のようにします。
Start-Sleep 3
これで3秒スリープします。また、
Start-Sleep -Seconds 3
でも同様です。秒でなくミリ秒で指定したい場合は、
Start-Sleep -Milliseconds 3000
か、もしくは
Start-Sleep -m 3000
で可能です。ちなみに、
Sleep 3
sleep 3
SLEEP 3
でも同じ動作をします。PowerShellのコマンドレットは、大文字小文字が違っていても問題ありません。
エイリアスでsleepと定義されている
Start-SleepではなくSleepでも動作する理由は、エイリアス機能でそのように定義されているからです。PowerShellで以下のように入力してください。
Get-Alias
するとエイリアスの定義がずらっと出てきますが、その中に以下があります。
Alias sleep -> Start-Sleep
これにより、Sleepでも動作するのです。
PowerShellでコマンドプロンプトのTIMEOUTを使える
コマンドプロンプトにはTIMEOUTというStart-Sleepに似たコマンドがあります。PowerShellでこれを使うには以下のようにします。
cmd /c timeout 3
これを実行すると以下のようなメッセージが出て3秒待ちます。数字はカウントダウンで変化します。
3 秒待っています。続行するには何かキーを押してください …
ただしメッセージにあるように、Start-Sleepとは違い何かキーを押すと終了します。
CTRL+Cでスリープは中断される
TIMEOUTで何かのキーを押しても無視して待つようにするには、以下のようにします。
cmd /c timeout 3 /nobreak
すると以下のような表示が出て3秒待ちます。
3 秒待っています。終了するには CTRL+C を押してください …
表示にあるように、CTRL+Cでは止めることが出来てしまいます。ただしこれはPowerShellのStart-Sleepも同様で、CTRL+Cでは中断されます。
PowerShellでTIMEOUTを実現できる?
Start-SleepでTIMEOUTのようにメッセージを出すにはどうしたらよいのでしょうか。以下のようにすればメッセージが出ます。
Write-Host 3秒おまちください;Start-Sleep 3
しかしTIMEOUTのようにカウントダウンはされません。以下のように関数を作れば、1秒毎にメッセージが出せます。
function self_sleep {
param ([Int]$second)
for ($i = 0; $i -lt $second; $i++) {
Write-Host ($second-$i) 秒お待ちください。
Start-Sleep 1
}
}
functionでTIMEOUTに近い処理を実現
上の関数を管理者権限で起動したWindows PowerShell ISEで入力して、ps1ファイルとして保存します。次に、
Set-ExecutionPolicy RemoteSigned
でps1ファイルを実行できるようにして、ps1ファイルを実行します。そして
self_sleep 3
を実行すると、以下のように表示が出て3秒待ちます。
3 秒お待ちください。
2 秒お待ちください。
1 秒お待ちください。
とはいえこれでもTIMEOUTと動作は違います。また1秒毎にsleepが途切れるので、ごくわずかですが、指定した秒数より遅延します。TIMEOUTの動作の方が良ければ、素直にcmd /c timeoutを使いましょう。
Sleepの使い道
そもそもSleepは何の役にたつのでしょうか。例えば以下のようにすれば、180秒後に音を鳴らせます。キッチンタイマーとして使えます。
Start-Sleep 180;echo `a
他には、後で何かのアプリを立ち上げて作業をしなければならない、と言った時には以下のようなことが出来ます。
Start-Sleep 600;notepad.exe c:\test\test.txt
こうすれば10分後にメモ帳でテキストファイルが開きます。PowerShellはWindows標準なので、何かのスケジュールアプリを入れずにできるのは便利でしょう。
Windowsのシステムをスリープさせる
PowerShellでのSleepを、Windowsのシステム自体をスリープする、と捉えた場合も解説しましょう。PowerShellに以下を入力することで、PCをスリープさせられます。
Add-Type -Assembly System.Windows.Forms;[System.Windows.Forms.Application]::SetSuspendState(‘Suspend’, $false, $false);
SetSuspendStateについて
AddTypeは外部システムのAPIを呼び出せます。それにより.Net FrameworkのSetSuspendStateを呼び出して実行します。SetSuspendStateは以下のように定義されています。
SetSuspendState (PowerState state, bool force, bool disableWakeEvent);
state 移行後の電源の動作モードを示す
force 強制的に中断モードにする場合は true
disableWakeEvent wake イベントでアクティブにならないようにするには true
休止モードとサスペンドモード
SetSuspendStateの1つ目のパラメータのstateは、Hibernateの場合は休止モード、Suspendの場合はサスペンドモードになります。休止モードはメモリの通電を切るので電源オフに近い状態です。一方のサスペンドモードは画面が消えるだけの省電力モードです。
省電力モードは復帰に時間がかかりますが、サスペンドモードはすぐ復帰できます。スリープといった場合、やりたいのは省電力モードでしょう。
そして2つ目のパラメータのforceは、あまり意味はありません。
SetSuspendStateのパラメータは正しく設定すること
3つ目のdisableWakeEventは重要で、これがtrueだとwakeイベントを無視するのでキーやマウスを入力しても復帰しません。そのためfalseにします。
SetSuspendState(‘Suspend’, $false, $false);としている理由は以上になります。スリープする場合は、1つめと3つ目のパラメータは正しく設定する必要があります。
rundll32.exeではスリープしないこと
ところがネットで、PowerShellでスリープする方法を調べると、以下のように書いている場合があります。
rundll32.exe PowrProf.dll,SetSuspendState
簡単なのでこれでやってしまいそうにいなりますが、SetSuspendStateのパラメータがありません。そうすると自動的に””休止モード””,true,trueになります。するとwakeイベントを受け付けず、キーやマウスで戻らず電源ボタンを押すしかなくなります。スリープでこれは意図していないでしょう。この方法でスリープするのはやめましょう。
PowerShellのSleepを活用しよう!
PowerShellのSleepを解説しましたが、ご理解頂けましたでしょうか。二種類のスリープについて解説しましたが、どちらもよく理解しておきましょう。
インフラエンジニア専門の転職サイト「FEnetインフラ」
FEnetインフラはサービス開始から10年以上『エンジニアの生涯価値の向上』をミッションに掲げ、多くのエンジニアの就業を支援してきました。
転職をお考えの方は気軽にご登録・ご相談ください。
