バッチファイルやPowerShellスクリプトを再起動後に自動で再開させる方法

バッチファイルやPowerShellスクリプトを再起動後に自動で再開させる方法。

WindowsでバッチファイルやPowerShellスクリプトを実行する場合、途中で再起動などで処理を中断しなければならないケースがあります。そのようなときは、再起動後に中断した個所から自動で再開できると便利です。

そこでここでは、バッチファイルやPowerShellスクリプトの処理を再起動を挟んで途中から再開させる方法を解説します。

再起動後にスクリプトを自動実行させる方法

バッチファイルやPowerShellスクリプトの処理を再起動を挟んで途中から再開するには、再起動後にバッチファイルやPowerShellスクリプトを自動的に実行させる処理と、再開箇所を指定する処理が必要になります。

再起動後にバッチファイルやPowerShellスクリプトを自動的に再実行させるには、以下の3通りの方法があります。

  • レジストリ設定を用いた方法
  • スタートアップフォルダーを用いた方法
  • タスクスケジューラを用いた方法

レジストリ設定を用いた方法

バッチファイルやPowerShellスクリプトを再起動後に自動的に再実行させる方法としておすすめなのは、レジストリのRunOnceキーに登録する方法です。

具体的には、以下のレジストリキーに次にWindowsにサインインしたときに実行するバッチファイルやPowerShellスクリプトを登録します。

レジストリキー:HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce

たとえば、PowerShellなら再起動の直前に以下のようにコマンドを記述することでレジストリ設定ができます。

Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce' -Name 'ResumeScript' -Value 'powershell -File F:\test1.pas1'

なお、RunOnceキーに登録した内容は一度実行されると自動的に消去されるので、登録した内容が残存しない点でもおすすめです。

スタートアップフォルダーを用いた方法

バッチファイルやPowerShellスクリプトを再起動後に自動的に再実行させる方法として最も簡単なのは、スタートアップフォルダーにスクリプトのショートカットファイルを配置する方法です。

ショートカットファイル自体はバッチファイルやPowerShellスクリプト内でも作成できますが、あらかじめショートカットファイルを作成しておいて、再起動の直前にスクリプトのショートカットファイルをスタートアップフォルダーに配置する処理を記述するのがおすすめです。

PowerShellなら、再起動の直前に以下のようにコマンドを記述することで、スタートアップフォルダーにショートカットファイルを配置します。

Copy-Item "F:\test.bat.lnk" "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\"

なお、スタートアップフォルダーに配置したショートカットファイルは、実行後に削除する処理を記述する必要があります。

タスクスケジューラを用いた方法

バッチファイルやPowerShellスクリプトを再起動後に自動的に再実行させる際に、管理者として自動実行させたいときは、再起動前にバッチファイルやPowerShellスクリプトを実行するタスクを作成します。

PowerShellなら、再起動の直前に以下のようにコマンドを記述します。

$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -File F:\test.ps1"
$Trigger = New-ScheduledTaskTrigger -AtLogOn
$Principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest -LogonType Interactive

Register-ScheduledTask -TaskName "ResumeScriptAfterReboot" -Action $Action -Trigger $Trigger -Principal $Principal -Force

なお、登録したタスクは、実行後に削除する処理を記述する必要があります。

処理の再開箇所を指定する方法

再起動後にバッチファイルやPowerShellスクリプトの再開箇所を指定するには、フラグファイル(進捗を記録するファイル)を使った方法が一般的です。

ここでは、分かりやすい方法としてメニュー形式のバッチファイルやPowerShellスクリプトで、メニーの途中から再開させる方法を紹介します。

バッチファイルの場合

バッチファイルの場合は、フラグファイルが存在すればフラグファイルに記述されている箇所から処理を実行させる処理を記述し、再起動の直前には再開箇所をフラグファイルに記録する処理を記述します。

以下のバッチファイルでは、1番の処理後に再起動させて、メニューの2番目から再開させるようフラグファイルに「2」と記録しています。

@echo off
:menu
echo -----------------
echo ■ メニュー ■
echo -----------------
echo 1:処理1
echo 2:処理2
echo 3:処理3
echo x:終了
echo -----------------

set flagFile="F:\flag.txt"
if exist %flagFile% (
    set /p errorlevel=<%flagFile%
) else (
    choice /c 123x /m 実行する処理番号を入力してください。:
)

if %errorlevel% LEQ 1 (
    echo ここに処理1の内容を記述します。
    echo 2>%flagFile%
    shutdown /r /t 0
)

if %errorlevel% LEQ 2 (
    echo ここに処理2の内容を記述します。
)

if %errorlevel% LEQ 3 (
    echo ここに処理3の内容を記述します。
    del %flagFile%
)

if %errorlevel% EQU 4 (
    goto :EOF
)

PowerShellスクリプトの場合

PowerShellスクリプトの場合もバッチファイルの場合と同じように、フラグファイルが存在すればフラグファイルに記述されている箇所から処理を実行させる処理を記述し、再起動の直前には再開箇所をフラグファイルに記録する処理を記述します。

以下のPowerShellスクリプトでは、2番の処理後に再起動させて、メニューの3番目から再開させるようフラグファイルに「3」と記録しています。

$menu = @"

-----------------------------------------------
■ ■ 作業メニュー PC名:$env:computername ■ ■
-----------------------------------------------
1:処理1
2:処理2
3:処理3
x:終了

"@

$Flg=$True
while($Flg) {
    $menu
    $flagFile = "F:\flg.txt"
    if (Test-Path $flagFile) {
        $inputValue = Get-Content $flagFile
    } else {
        $inputValue = Read-Host "実行する処理番号を入力してください。"
    }

    switch($inputValue) {
        { $_ -le 1 } {
            Write-Host "ここに処理1の内容を記述します。"

            if ((Read-Host "終了[e]") -eq "e"){break}
        }
        { $_ -le 2 } {
            Write-Host "ここに処理2の内容を記述します。"
            Set-Content  -Path $flgFile -Value "3"
            Restart-Computer -Force

            if ((Read-Host "終了[e]") -eq "e"){break}
        }
        { $_ -le 3 } {
            Write-Host "ここに処理3の内容を記述します。"
            Remove-Item $flagFile
            if ((Read-Host "終了[e]") -eq "e"){break}
        }
        { $_ -eq "x" } {
            $Flg=$False
            break
        }
        default {
            Write-Host "正しい番号を入力してください。"
        }
    }
}