TypeScript のスクリプトを毎朝実行したいだけなのに、ターミナルを開いたままにしたり、実行し忘れたりするのは面倒です。
今回は、Windows タスクスケジューラを使って、ローカルプロジェクトの tsx スクリプトを毎日決まった時刻に実行する手順をまとめます。
実際に試して安定した構成は、次の3点です。
-
tsxはプロジェクトのローカル依存関係としてインストールする - 実行用の
.cmdファイルを作る - タスクスケジューラから
.cmdファイルを起動する
タスクスケジューラから直接 tsx を呼ぶよりも、作業ディレクトリやログ出力を明示できるため、トラブルの切り分けが簡単です。
1. tsx プロジェクトを用意する
まず、実行対象のプロジェクトを作成します。今回は C:\work\daily-job に配置する例です。
New-Item -ItemType Directory -Force C:\work\daily-job
Set-Location C:\work\daily-job
npm init -y
npm install -D tsx typescript @types/node
src\main.ts を作成し、動作確認用に次のコードを書きます。
const now = new Date().toLocaleString("ja-JP");
console.log(`daily job started: ${now}`);
// 実際の処理をここに書く
// 例: APIからデータを取得する、ファイルを整理する、集計結果を保存する
手動で実行できることを確認します。
npx tsx src\main.ts
次のように表示されれば準備完了です。
daily job started: 2026/9/24 8:00:00
この時点で実行できない場合は、タスクスケジューラの設定に進まず、まず tsx や TypeScript のエラーを解消します。
2. Windows 用の実行ファイルを作る
タスクスケジューラから直接 npx tsx src\main.ts を実行する方法もあります。しかし、タスクスケジューラは通常のターミナルと環境変数や作業ディレクトリが異なります。
そこで、プロジェクト直下に run-daily.cmd を作ります。
@echo off
setlocal
cd /d C:\work\daily-job
if not exist logs mkdir logs
echo [%date% %time%] start>> logs\daily.log
node_modules\.bin\tsx.cmd src\main.ts>> logs\daily.log 2>&1
set EXIT_CODE=%ERRORLEVEL%
echo [%date% %time%] exit=%EXIT_CODE%>> logs\daily.log
exit /b %EXIT_CODE%
ポイントは、node_modules\.bin\tsx.cmd を直接指定していることです。
これにより、グローバルインストールされた tsx や、タスクスケジューラ側の PATH に依存しません。また、標準出力とエラー出力を logs\daily.log に保存しています。
PowerShell から実行して、ログを確認します。
C:\work\daily-job\run-daily.cmd
Get-Content C:\work\daily-job\logs\daily.log
ログに次のような内容が追加されていれば成功です。
[2026/09/24 08:00:00.00] start
daily job started: 2026/9/24 8:00:00
[2026/09/24 08:00:01.00] exit=0
実際に設定してみると、このログがあるだけで「実行されなかった」のか「実行されたがスクリプトで失敗した」のかを判断しやすくなります。
3. タスクスケジューラに登録する
スタートメニューで「タスク スケジューラ」を検索して起動します。
右側の「基本タスクの作成」をクリックし、次のように設定します。
基本タスクの作成
名前には、分かりやすい名前を入力します。
Daily TypeScript Job
トリガーは「毎日」を選び、実行時刻を指定します。たとえば毎朝8時に実行する場合は、開始時刻を 08:00 にします。
操作では「プログラムの開始」を選び、以下を入力します。
プログラムまたはスクリプト:
C:\work\daily-job\run-daily.cmd
通常はこれだけで実行できます。もし .cmd ファイルを直接指定してうまく動かない場合は、次のように cmd.exe 経由で設定します。
プログラムまたはスクリプト:
C:\Windows\System32\cmd.exe
引数の追加:
/c "C:\work\daily-job\run-daily.cmd"
「完了」を押したら、作成したタスクを右クリックして「プロパティ」を開きます。
「全般」タブでは、必要に応じて次を設定します。
- 「ユーザーがログオンしているかどうかにかかわらず実行する」
- 「最上位の特権で実行する」
ファイル操作や他のアプリケーションへのアクセスで権限が必要な処理の場合は、「最上位の特権で実行する」を有効にします。ただし、不要な権限は付けない方が安全です。
「条件」タブにある「コンピューターをAC電源で使用している場合のみタスクを開始する」は、ノートPCでバッテリー動作中にも実行したい場合は無効にします。
4. すぐに実行して確認する
登録直後に動作確認するには、タスクスケジューラの一覧からタスクを選び、右側の「実行」をクリックします。
または、コマンドから実行できます。
schtasks /Run /TN "Daily TypeScript Job"
数秒待ってからログを確認します。
Get-Content C:\work\daily-job\logs\daily.log -Wait
「最終実行結果」が 0x0 なら、基本的には正常終了です。
schtasks /Query /TN "Daily TypeScript Job" /V /FO LIST
一方で、タスクの状態が「実行中」のままになったり、ログが作成されなかったりする場合は、次の点を確認します。
-
C:\work\daily-jobのパスが正しいか -
node_modulesが存在するか -
node_modules\.bin\tsx.cmdが存在するか - 実行ユーザーにプロジェクトフォルダーへの権限があるか
- スクリプト内で相対パスを使っていないか
相対パスを使う処理がある場合でも、今回の .cmd では最初に cd /d C:\work\daily-job を実行しているため、プロジェクトを基準に動かせます。
5. 環境変数や秘密情報を扱う場合
APIキーなどを使うスクリプトでは、.cmd に直接秘密情報を書かないようにします。
たとえば、プロジェクト直下に .env を置き、dotenv で読み込む方法があります。
npm install dotenv
import "dotenv/config";
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error("API_KEY is not set");
}
console.log("API key is available");
.env は Git 管理から除外します。
node_modules/
.env
logs/
ただし、タスクスケジューラはログオン中のターミナルと同じ環境変数を必ずしも持っていません。ユーザー環境変数に依存する場合は、タスクの実行ユーザーと環境変数の設定場所を確認してください。
今回のような個人用スクリプトであれば、まずはログ出力を用意し、成功・失敗を確認できる状態にしておくことが重要です。
まとめ
Windows で tsx スクリプトを毎日実行する場合は、次の構成が扱いやすいです。
タスクスケジューラ
↓
run-daily.cmd
↓
node_modules\.bin\tsx.cmd
↓
src\main.ts
最短の実装は、プロジェクト内の tsx.cmd を明示的に呼び出す .cmd ファイルを作り、それをタスクスケジューラに登録する方法です。
実際に検証したところ、作業ディレクトリとログ出力を .cmd にまとめておくことで、手動実行と自動実行の差も小さくできました。まずは schtasks /Run で即時実行し、daily.log と終了コード 0x0 を確認してから、毎日のスケジュールを有効にするのがおすすめです。