バッチファイルを「PC起動のたびに自動で実行したい」という要望はよくあります。ただし実行タイミング(システム起動 vs ログオン)・権限(SYSTEM vs ユーザー)・適用範囲(全ユーザー vs 特定ユーザー)によって使うべき方法が異なります。
本記事ではスタートアップフォルダ・タスクスケジューラ(schtasks コマンド)・レジストリ Run キーの3方式を比較し、ネットワーク接続待ち・遅延実行・管理者権限での自動実行まで実践コードで解説します。
- スタートアップフォルダへの登録方法(ユーザー用・全ユーザー用)
- タスクスケジューラで「PC起動時」「ログオン時」トリガーをコマンドで登録する方法
- 遅延実行(起動直後ではなく5分後に実行)の設定
- レジストリ Run キーへの登録方法(reg add)
- 起動時にネットワーク接続が完了するまで待機する処理
- 管理者権限が必要な処理を起動時に自動実行する方法
3つの自動実行方法の比較
| 方法 | 実行タイミング | 実行権限 | 適用範囲 | 設定難度 |
|---|---|---|---|---|
| スタートアップフォルダ | ログオン後 | ログオンユーザー | ユーザー / 全ユーザー | 低(ファイルを置くだけ) |
| タスクスケジューラ(onlogon) | ログオン後 | 指定ユーザー / SYSTEM | ユーザー / 全ユーザー | 中(コマンドまたはGUI) |
| タスクスケジューラ(onstart) | PC起動直後(ログオン前) | SYSTEM | 全ユーザー | 中(管理者権限必要) |
| レジストリ Run キー(HKCU) | ログオン後 | ログオンユーザー | 特定ユーザーのみ | 中(reg add コマンド) |
| レジストリ Run キー(HKLM) | ログオン後 | ログオンユーザー | 全ユーザー | 高(管理者権限必要) |
PC起動時(onstart)はWindowsが立ち上がった直後でログオン前に実行されます。SYSTEM権限で動作し、デスクトップもありません。サービス起動・ネットワーク初期化などOS全体に影響する処理に向いています。
ログオン時(onlogon / スタートアップ)はユーザーがサインインした後に実行されます。デスクトップが使え、ユーザーのファイルやネットワークドライブにアクセスできます。個人の作業準備や環境設定に向いています。
スタートアップフォルダに登録する(最も手軽)
バッチファイルのショートカットをスタートアップフォルダに置くだけで、ログオン時に自動実行されます。管理者権限も不要で最も手軽な方法です。
REM 現在のユーザーのみ(ログオンユーザーだけ実行) C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup REM すべてのユーザー(誰がログオンしても実行) C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp REM Win+R から直接開くショートカット shell:startup REM 現在ユーザーのスタートアップ shell:common startup REM 全ユーザーのスタートアップ(管理者権限必要)
@echo off
REM バッチファイルのショートカットをスタートアップフォルダに作成する
REM PowerShell の WScript.Shell で .lnk ファイルを作成
set SCRIPT_PATH=C:\scripts\my_startup.bat
set STARTUP_DIR=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
set SHORTCUT=%STARTUP_DIR%\my_startup.lnk
powershell -Command "$ws=New-Object -ComObject WScript.Shell; $sc=$ws.CreateShortcut('%SHORTCUT%'); $sc.TargetPath='%SCRIPT_PATH%'; $sc.Save()"
echo ショートカットを作成しました: %SHORTCUT%
スタートアップフォルダから実行するとコマンドプロンプトのウィンドウが表示されます。バックグラウンドで実行したい場合は、ショートカットのプロパティで「実行時の大きさ」を「最小化」に設定するか、タスクスケジューラの「ユーザーがログオンしているかどうかにかかわらず実行する」+ ウィンドウ非表示設定を使います。
タスクスケジューラで起動・ログオン時に登録する(schtasks コマンド)
schtasks コマンドを使えばGUI操作なしでタスクを登録できます。バッチファイル自体の中から自動登録する仕組みを作ることも可能です。
@echo off
REM ログオン時にバッチを実行するタスクを登録
REM /sc onlogon : ログオンのたびに実行
REM /ru %USERNAME% : 現在のユーザーで実行
REM /rl highest : 管理者として実行(不要ならこの行を削除)
schtasks /create ^^
/tn "MyLogonTask" ^^
/tr "C:\scripts\logon_startup.bat" ^^
/sc onlogon ^^
/ru "%USERNAME%" ^^
/rl highest ^^
/f
if %ERRORLEVEL% equ 0 (
echo タスク登録成功
) else (
echo タスク登録失敗 ERRORLEVEL=%ERRORLEVEL%
)
@echo off REM PC起動時(ログオン前)に SYSTEM 権限で実行 REM ※ このコマンドは管理者として実行する必要があります schtasks /create ^^ /tn "MyStartupTask" ^^ /tr "C:\scripts\boot_task.bat" ^^ /sc onstart ^^ /ru SYSTEM ^^ /f echo 起動時タスクを登録しました REM 登録内容を確認 schtasks /query /tn "MyStartupTask" /fo LIST
@echo off REM ログオンから5分後に実行(起動直後の高負荷を避ける) REM /delay HH:MM 形式で遅延時間を指定 schtasks /create ^^ /tn "DelayedStartupTask" ^^ /tr "C:\scripts\delayed_task.bat" ^^ /sc onlogon ^^ /delay 0000:05 ^^ /ru "%USERNAME%" ^^ /f echo 5分遅延の起動タスクを登録しました
PC起動直後は多くのプロセスが同時に起動して高負荷になります。バックアップ・同期・監視スクリプトなど重い処理は
/delay で数分遅らせることで、起動時の応答遅延を避けられます。タスクスケジューラのより詳細な使い方はタスクスケジューラと連携して定期処理を自動化する方法、schtasks コマンドの登録・削除操作はバッチでタスクスケジューラを登録・削除する方法を参照してください。レジストリ Run キーに登録する
レジストリの Run キーに登録する方法は古くから使われる手法です。HKCU(現在のユーザーのみ)と HKLM(全ユーザー)の2種類があります。
@echo off REM ログオン時にバッチを実行(現在のユーザーのみ) reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" ^^ /v "MyBatchApp" ^^ /t REG_SZ ^^ /d "C:\scripts\my_startup.bat" ^^ /f echo レジストリに登録しました REM 確認 reg query "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v "MyBatchApp"
@echo off REM 全ユーザーのログオン時に実行(管理者権限で実行する必要あり) reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" ^^ /v "MyBatchApp" ^^ /t REG_SZ ^^ /d "C:\scripts\my_startup.bat" ^^ /f echo 全ユーザー用レジストリに登録しました REM 登録削除する場合 REM reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v "MyBatchApp" /f
レジストリは Windowsの重要な設定データベースです。誤った操作はシステムに影響する可能性があります。
reg add の前に reg export でバックアップを取ることを推奨します。また RunOnce キー(HKCU\...\RunOnce)を使うと次回ログオン時に1回だけ実行して自動的に削除される動作になります。起動時にネットワーク接続が完了するまで待機する
ネットワークドライブへのアクセスやファイル転送など、ネットワークが必要な処理をログオン直後に実行すると接続前で失敗することがあります。ping を使ってネットワーク接続を確認してから処理を開始するパターンです。
@echo off
setlocal
set LOGFILE=C:\logs\startup.log
if not exist "C:\logs" mkdir "C:\logs"
set T=%TIME: =0%
echo [%T:~0,8%] スタートアップ開始 >> "%LOGFILE%"
REM ネットワーク接続を最大30回(約150秒)待機
set RETRY=0
:wait_network
set /a RETRY+=1
if %RETRY% gtr 30 (
echo [WARN] ネットワーク接続タイムアウト >> "%LOGFILE%"
goto :network_skip
)
ping -n 1 8.8.8.8 >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo [%RETRY%/30] ネットワーク待機中... >> "%LOGFILE%"
timeout /t 5 /nobreak >nul
goto wait_network
)
:network_skip
set T=%TIME: =0%
echo [%T:~0,8%] ネットワーク接続確認 >> "%LOGFILE%"
REM ネットワーク接続後の処理をここに記述
net use Z: \\server\share >nul 2>&1
echo [%T:~0,8%] ネットワークドライブ接続完了 >> "%LOGFILE%"
endlocal
ping -n 1 8.8.8.8 でインターネット接続を確認しています。社内ネットワークのみ使う場合はデフォルトゲートウェイ(ipconfig で確認)や社内サーバーの IP アドレスに変えてください。-n 1 は1回だけ ping を送るオプションです。管理者権限が必要な処理を起動時に自動実行する
サービスの起動・システム設定の変更など管理者権限が必要な処理をPC起動時に自動実行するには、タスクスケジューラで「最上位の特権で実行する」(/rl highest)を設定します。
@echo off
REM このバッチ自体を管理者として実行する必要があります
REM 管理者権限確認
net session >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo 管理者権限で実行してください。
pause
exit /b 1
)
REM ログオン時に管理者権限で実行するタスクを登録
schtasks /create ^^
/tn "AdminStartupTask" ^^
/tr "C:\scripts\admin_task.bat" ^^
/sc onlogon ^^
/ru "%USERNAME%" ^^
/rl highest ^^
/f
echo 管理者権限での起動タスクを登録しました
@echo off
REM タスクスケジューラから実行すると作業ディレクトリが変わることがある
REM %~dp0 で自分自身のフォルダを基準にパスを指定する
set SCRIPT_DIR=%~dp0
REM 設定ファイルはスクリプトと同じフォルダを参照
set CONFIG=%SCRIPT_DIR%config.ini
set LOGFILE=%SCRIPT_DIR%startup.log
echo 起動処理開始 %DATE% %TIME% >> "%LOGFILE%"
if exist "%CONFIG%" (
echo 設定ファイル読み込み: %CONFIG% >> "%LOGFILE%"
) else (
echo [ERROR] 設定ファイルが見つかりません: %CONFIG% >> "%LOGFILE%"
exit /b 1
)
タスクスケジューラから実行すると、カレントディレクトリが
C:\Windows\System32 などに変わります。相対パスを使うと意図しない場所を参照して失敗します。%~dp0(バッチファイル自身のフォルダパス)で絶対パスを構成することで防げます。詳細はバッチファイルで相対パスを指定する完全ガイドを参照してください。管理者権限の自動実行全般については管理者権限で自動実行するバッチファイルの作り方も参照してください。実践:起動ログを記録する完全なスタートアップバッチ
これまでの内容を組み合わせた実践的なスタートアップバッチファイルです。ログオン時の日時・ネットワーク接続確認・各処理の実行結果を記録します。
@echo off
setlocal enabledelayedexpansion
REM --- 設定 ---
set LOGFILE=%~dp0startup_%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%.log
REM --- 開始ログ ---
echo ========================================= >> "%LOGFILE%"
echo ログオン: %DATE% %TIME% ユーザー: %USERNAME% >> "%LOGFILE%"
echo ========================================= >> "%LOGFILE%"
REM --- ネットワーク待機(最大60秒)---
set WAIT=0
:wait_net
ping -n 1 8.8.8.8 >nul 2>&1
if %ERRORLEVEL% equ 0 goto net_ok
set /a WAIT+=5
if !WAIT! geq 60 (
echo [WARN] ネットワークタイムアウト >> "%LOGFILE%"
goto net_skip
)
timeout /t 5 /nobreak >nul
goto wait_net
:net_ok
echo [OK] ネットワーク接続確認(待機: !WAIT!秒) >> "%LOGFILE%"
:net_skip
REM --- 各処理を実行してERRORLEVELをログに記録 ---
call :run_task "ネットワークドライブ接続" "net use Z: \\server\share"
call :run_task "同期処理" "robocopy C:\local D:\backup /mir /log+:"%~dp0sync.log" /r:1 /w:1"
echo 完了: %TIME% >> "%LOGFILE%"
goto :eof
:run_task
REM 引数: %1=タスク名, %2=実行コマンド
%~2 >nul 2>&1
if %ERRORLEVEL% equ 0 (
echo [OK] %~1 >> "%LOGFILE%"
) else (
echo [NG] %~1 ERRORLEVEL=%ERRORLEVEL% >> "%LOGFILE%"
)
goto :eof
まとめ
- スタートアップフォルダ: ショートカットを置くだけ・手軽・ウィンドウが開く
- タスクスケジューラ onlogon: ログオン後実行・ウィンドウ非表示可・遅延実行可
- タスクスケジューラ onstart: ログオン前・SYSTEM権限・管理者権限が必要な処理向け
- レジストリ Run: HKCU(ユーザー)/ HKLM(全ユーザー)・reg add で登録
- 遅延実行:
/delay 0000:05で5分遅らせて起動負荷を分散 - ネットワーク待機: ping ループでネットワーク確認後に処理開始
- %~dp0 を使う: タスクスケジューラ実行時はカレントディレクトリが変わるため必須
関連記事: タスクスケジューラと連携して定期処理を自動化する方法 / 管理者権限で自動実行するバッチファイルの作り方 / バッチファイルで相対パスを指定する完全ガイド
よくある質問(FAQ)
C:\Windows\System32 になります。バッチファイル内で相対パスを使っていると、そこを基準に解決されてファイルが見つからなくなります。set SCRIPT_DIR=%~dp0 でバッチファイル自身のフォルダを取得し、%SCRIPT_DIR%config.ini のように絶対パスで指定することで解決できます。詳細は相対パス指定の完全ガイドを参照してください。onstart(コンピューターの起動時)はWindowsが起動した直後・ログオン前に実行されます。GUIがなく SYSTEM 権限で動作します。onlogon(ログオン時)はユーザーがサインインした後に実行され、デスクトップが使えます。多くのスタートアップ用途には onlogon が適しています。schtasks /delete /tn "タスク名" /f で削除できます。レジストリの場合は reg delete "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" /v "値名" /f で削除します。schtasks の登録・削除操作の詳細はバッチでタスクスケジューラを登録・削除する方法を参照してください。ping -n 1 ゲートウェイIP >nul 2>&1 でループしてネットワーク接続を確認してから処理を開始してください。または /delay 0000:02 オプションで2分遅らせてから実行することで回避できる場合もあります。また HKLM\SYSTEM\CurrentControlSet\Control\NetworkProvider\HwOrder の設定でネットワーク初期化タイミングを調整する方法もあります。

