しばしば任意の時刻でWindowsを自動で落としたい時があります。定期的なものであればタスクスケジューラなりなんなりを使うのですが、一時的なものであったりよく時刻が変わるようなものであれば、毎回楽な手打ちをしたくなります。これは例えば、時間を忘れてパソコンを使い倒して睡眠時間が削れすぎるのを防ぐ目的で使えます。
実際のコードが次です。
# 時刻の入力
$targetTime = Read-Host "どの時刻にシステムをシャットダウン、休止、またはスリープさせますか?(例:09:30、12:34)"
# 時刻形式のチェック
try {
$targetDateTime = [DateTime]::ParseExact($targetTime, "HH:mm", $null)
} catch {
Write-Host "入力された時刻が正しい形式(HH:mm)ではありません。"
# コンソールを開いたままにするために、スクリプトの終了を防ぐ
Read-Host -Prompt "Enterを押して終了"
return
}
# アクションの選択
$action = Read-Host "シャットダウン(D)、休止(H)、スリープ(S)のいずれかを選択してください"
# アクションの文字列変換
switch ($action) {
"D" { $actionString = "シャットダウン" }
"H" { $actionString = "休止" }
"S" { $actionString = "スリープ" }
}
# 確認
$confirmation = Read-Host "$targetTime に $actionString する。この設定でよろしいですか? (Y/N)"
# 時刻の計算
$currentTime = Get-Date
if ($targetDateTime -lt $currentTime) {
$targetDateTime = $targetDateTime.AddDays(1)
}
$delay = $targetDateTime - $currentTime
# アクションの実行
Write-Host "$actionString をキャンセルするには、このコンソールを閉じてください。"
if ($confirmation -eq "Y") {
do {
$remainingTime = $targetDateTime - (Get-Date)
Write-Host "`r待機中:$actionString - 残り時間:$($remainingTime.Hours)時間 $($remainingTime.Minutes)分 $($remainingTime.Seconds)秒" -NoNewline
Start-Sleep -Seconds 1
} while ($targetDateTime -gt (Get-Date))
Write-Host ""
switch ($action) {
"D" {
# シャットダウン
Stop-Computer
break
}
"H" {
# 休止
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::SetSuspendState([System.Windows.Forms.PowerState]::Hibernate, $false, $false)
break
}
"S" {
# スリープ
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::SetSuspendState([System.Windows.Forms.PowerState]::Suspend, $false, $false)
break
}
}
} else {
Write-Host "キャンセルされました。"
}
使い方はpowershell 上記スクリプトが書かれたファイルとするか既定のプログラムをWindows PowerShellにした上記スクリプトファイルをダブルクリックするかです。実行が始まれば対話にしたがって何時何分にどうするかを決定して待つだけです。
実行例のスクリーンショットが次です。
