手動では動くPython処理をWindowsの自動実行へ移すときは、スケジュール設定そのものよりも「どのプロセスが、どの場所で、どの環境を使って起動されたか」を固定することが重要です。この記事では、特定のPCや運用サービスに依存しない切り分け順を整理します。
1. まず実際に起動されたPythonを確認する
PATH上のpythonが意図した実行ファイルとは限りません。手動のPowerShellと、タスクから起動したプロセスの両方で次を確認します。
where.exe python
Get-Command python
python -c "import sys; print(sys.executable)"
sys.executableは現在のPythonインタープリターの実行ファイルを示します。仮想環境を使う場合は、タスクからも仮想環境のScripts\python.exeを直接指定すると、PATH解決の差を減らせます。
2. Task SchedulerのProgram/scriptを実行ファイルにする
Task Schedulerのアクションでは、Program/scriptに実行するプログラム、Add argumentsにその引数を分けて指定します。実環境のパスは記事中で決め打ちせず、対象PCの確認結果を採用してください。
Program/script:
C:\path\to\project\.venv\Scripts\python.exe
Add arguments:
"C:\path\to\project\run_job.py" --mode scheduled
Start in:
C:\path\to\project
C:\path\to\projectは説明用の例です。存在するパスとして扱わないでください。
3. Start inと相対パスをセットで確認する
スクリプトがdata\input.csvのような相対パスを使うと、作業フォルダが異なるだけで失敗します。タスク設定のStart inを確認し、コード側でも必要ならスクリプト位置から絶対パスを組み立てます。
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
input_path = BASE_DIR / "data" / "input.csv"
診断時は、次の値をログへ残すと手動実行との差が見えます。
import os
from pathlib import Path
import sys
print("executable=", sys.executable)
print("cwd=", Path.cwd())
print("path=", os.environ.get("PATH", ""))
4. PATHと仮想環境の差を確認する
Pythonのコマンドライン動作は環境変数の影響を受けます。手動のシェルで設定されたPATHやPYTHONPATHが、タスクの実行コンテキストでも同じとは限りません。環境変数を増やして解決を隠す前に、実行ファイルと依存ライブラリの場所を固定し、必要な値だけを明示します。
確認用のPowerShell例です。
& "C:\path\to\project\.venv\Scripts\python.exe" -c "import sys, os; print(sys.executable); print(os.getcwd()); print(os.environ.get('PATH',''))"
5. ユーザー、権限、ネットワークを同じ条件にする
タスクの実行ユーザーが手動実行のユーザーと異なると、ファイルアクセス、共有フォルダ、資格情報、プロファイル依存設定の結果が変わります。管理者権限を付ければよいと決めつけず、対象ファイルと必要な操作だけをその実行ユーザーが行えるか確認します。
特に、ユーザーのログオン状態、ネットワーク利用可否、ユーザープロファイルの有無は、タスク設定と処理の前提条件として分けて記録します。
6. stdoutとstderrをファイルへ分けて残す
タスクは対話画面を持たないため、画面に出した例外を後から確認できないことがあります。PowerShellから起動する場合は、標準出力と標準エラーを別ファイルへリダイレクトできます。
$log = "C:\path\to\logs\scheduled-python.log"
$err = "C:\path\to\logs\scheduled-python.err.log"
& "C:\path\to\project\.venv\Scripts\python.exe" "C:\path\to\project\run_job.py" *>> $log 2>> $err
exit $LASTEXITCODE
ログの保存先も相対パスにせず、書き込み権限を確認したディレクトリにします。秘密情報やアクセストークンを標準出力へ出さないことも、切り分けの前提です。
7. 再現は一項目ずつ行う
次の順で、手動実行とタスク実行の差を一つずつ埋めます。
sys.executableが一致しているか確認する。where.exe pythonとGet-Command pythonの結果を比較する。Path.cwd()とTask SchedulerのStart inを確認する。- 相対パスを一時的に検査ログへ出す。
- 実行ユーザーと対象ファイルの権限を確認する。
- PATH、
PYTHONPATH、必要な設定値の差を比較する。 - stdout、stderr、終了コードを保存して最初の失敗点を特定する。
よくある誤判定
pythonが見つからないだけなのに、Pythonコードのバグだと判断する。- 手動時のカレントディレクトリをタスクでも前提にする。
- 管理者権限を付けて症状が消えたことだけで、必要な権限を特定したと考える。
- ログが無いことを「処理が実行されなかった」と断定する。
- タスクの設定を変更しながら、どの変更で直ったかを記録しない。
最終チェックリスト
- [ ]
sys.executableが意図したPythonを示す - [ ]
where.exe pythonとGet-Command pythonを記録した - [ ] Program/script、Add arguments、Start inを分けて設定した
- [ ] 相対パスの基準ディレクトリを決めた
- [ ] PATHと仮想環境の依存関係を確認した
- [ ] 実行ユーザーと必要最小限の権限を確認した
- [ ] stdout、stderr、終了コードを保存した
- [ ] 一度に一つの条件だけ変更した
この記事は一般的な切り分け手順です。個別のWindowsポリシー、ネットワーク設定、権限設定は実行環境の管理者と確認してください。
筆者の環境で実際に確認した結果
確認日:2026年10月14日/環境:Windows 11 Home(ビルド26300)、Windows PowerShell 5.1、Python 3.14
同じPythonスクリプト(作業フォルダ・実行中のpython.exe・相対パスで settings.txt を開けるか・PATHの中身を記録するだけのもの)を、PowerShellから実行した場合と、タスクスケジューラに一時的に登録して実行した場合で比べました。python.exe はどれもフルパス(...\Python314\python.exe)で指定しています。
| 実行のしかた | 作業フォルダ(os.getcwd()) | 相対パスのファイル読み込み | PATHにPythonのフォルダ |
|---|---|---|---|
| PowerShellからスクリプトのフォルダで実行 | スクリプトのフォルダ | 成功 | あり |
| タスクスケジューラ(「開始(オプション)」が空) | C:\WINDOWS\system32 |
FileNotFoundError | なし |
| タスクスケジューラ(「開始(オプション)」にスクリプトのフォルダ) | スクリプトのフォルダ | 成功 | なし |
チェックリストのうち「作業フォルダ」と「PATH」の2項目は、実際にタスクから動かすと結果が変わりました。自動実行に載せる前に、ここで紹介したような記録用の数行を入れて一度タスクから動かしておくと安心です。
RIN WORK LABのツール:RIN Tools|AIエージェントの事故を減らす 個人開発テンプレ集[Claude Code編]
AIエージェントに作業を任せる前に、変更範囲・禁止事項・完了条件を整理するための指示書テンプレート集です。まずは無料サンプル(5ページPDF+指示書サンプル)で形式を確認できます。
無料サンプルを見る(BOOTH) / 有料版(1,500円)
※当サイトの運営者(RIN WORK LAB)がBOOTHで販売している商品です。
