TL;DR
0x1 = chương trình của task thoát với exit code khác 0 (lỗi chung). 0x41301 = task vẫn đang chạy — hoặc bị treo từ lần chạy trước. Danh sách kiểm tra nhanh:
- Chạy lệnh thủ công trong CMD trước. Nếu lỗi ở đó, sửa lệnh — không phải scheduler.
- Đặt "Start in" vào thư mục chứa script của bạn.
- Tick "Run whether user is logged on or not" + "Run with highest privileges".
- Với 0x41301: kill tiến trình bị treo và cấu hình stop timeout.
Các Mã Này Thực Sự Có Nghĩa Gì
Task Scheduler không tự sinh ra 0x1 — nó chỉ chuyển tiếp exit code mà chương trình của bạn trả về. Exit code 1 về cơ bản là tín hiệu "có gì đó bị hỏng" phổ quát của mọi ngôn ngữ. Python dùng nó. Bash dùng nó. Kể cả batch script cũng mặc định về nó. Đó là lý do 0x1 không cho bạn biết gì cụ thể; bạn phải nhìn vào chính chương trình đó.
0x41301 lại là một chuyện khác. Đây là mã nội bộ của Task Scheduler có nghĩa là task đang chạy rồi. Điều này xảy ra khi một instance trước chưa kết thúc mà trigger tiếp theo đã kích hoạt — ví dụ một job backup mất 90 phút nhưng được lên lịch chạy mỗi giờ.
Bước 1 — Tái Hiện Lỗi Thủ Công
Trước khi chỉnh bất kỳ cài đặt nào trong Task Scheduler, hãy mở CMD với cùng user mà task đang chạy và chạy chính xác lệnh đó. Chín lần trong mười, lỗi sẽ hiện ra ngay tại đó.
# Nếu task của bạn chạy PowerShell script:
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\backup.ps1"
# Kiểm tra exit code ngay sau đó:
echo %ERRORLEVEL%
ERRORLEVEL khác 0? Script bị lỗi rồi. Sửa script trước — scheduler chỉ là người đưa tin thôi.
Bước 2 — Sửa Thư Mục "Start In"
Cài đặt đơn lẻ này chiếm khoảng 40% trường hợp lỗi 0x1. Các script dùng đường dẫn tương đối (./config.json, ../logs/) sẽ âm thầm thất bại khi Task Scheduler khởi chạy chúng từ C:\Windows\System32.
Vào Task Scheduler → chuột phải vào task → Properties → tab Actions → Edit action:
- Program/script:
powershell.exe(hoặc đường dẫn đầy đủ đến file exe) - Arguments:
-ExecutionPolicy Bypass -File "C:\Scripts\backup.ps1" - Start in (optional):
C:\Scripts← trỏ vào thư mục chứa script của bạn
Bước 3 — Sửa Quyền Và User Context
Các task chạy "only when user is logged on" sẽ thừa hưởng phiên desktop của bạn. Chạy chúng nền thì chúng nhận một token bị giảm quyền — không có desktop, truy cập hạn chế. Đây là những gì cần sửa:
- Tab General → chọn "Run whether user is logged on or not"
- Tick "Run with highest privileges" nếu task cần quyền admin
- Nhập thông tin xác thực khi được hỏi — Task Scheduler sẽ mã hóa và lưu lại
Một bẫy nữa: nếu task truy cập network share, đừng chạy với tài khoản SYSTEM. Tài khoản SYSTEM không có thông tin xác thực mạng. Hãy dùng domain service account thực sự có quyền truy cập vào các đường dẫn đó.
Bước 4 — Bật Logging Để Xem Lỗi Thực Sự
Chuyển hướng output ra file log. Không có cái này bạn chỉ đang đoán mò.
<!-- Trong Action → Arguments của task: -->
-ExecutionPolicy Bypass -File "C:\Scripts\backup.ps1" >> "C:\Logs\backup.log" 2>&1
<!-- Hoặc bọc trong cmd.exe để redirect gọn hơn: -->
cmd.exe /c "powershell.exe -File C:\Scripts\backup.ps1 >> C:\Logs\backup.log 2>&1"
Cũng nên bật log operational của Task Scheduler trong Event Viewer — mặc định nó bị tắt:
# Applications and Services Logs → Microsoft → Windows → TaskScheduler → Operational
# Chuột phải → Enable Log
# Hoặc dùng một lệnh trong PowerShell:
wevtutil set-log Microsoft-Windows-TaskScheduler/Operational /enabled:true
Sau lần chạy tiếp theo, tìm event ID 201 (hoàn thành) hoặc 203/101 (thất bại kèm lý do). Event 101 đặc biệt sẽ cho bạn thông báo lỗi thực sự.
Sửa 0x41301 — Tiến Trình Bị Treo
Một lần chạy trước bị kẹt. Kill nó đi, rồi cài đặt biện pháp bảo vệ để tránh bị chồng chất lại.
# Tìm các task instance đang chạy:
Get-ScheduledTask | Where-Object {$_.State -eq 'Running'}
# Dừng một task cụ thể:
Stop-ScheduledTask -TaskName "YourTaskName" -TaskPath "\YourFolder\"
# Hoặc dùng schtasks:
schtasks /end /tn "\YourFolder\YourTaskName"
Sau đó mở Properties của task → tab Settings:
- "If the task is already running..." → đặt thành "Stop the existing instance" hoặc "Do not start a new instance"
- "Stop the task if it runs longer than" → đặt timeout cứng. Với hầu hết các job, 1–2 giờ là đủ.
PowerShell Scripts — Exit Code Quan Trọng Lắm
Một PowerShell script kết thúc mà không có lệnh exit tường minh sẽ trả về status code của lệnh cuối cùng. Nếu lệnh cuối đó thất bại — kể cả một Write-Host trúng file đang bị khóa — bạn sẽ nhận được 0x1. Hãy viết rõ ràng:
try {
# ... công việc của bạn ...
Write-Host "Done"
exit 0
} catch {
Write-Error $_.Exception.Message
exit 1 # lỗi có chủ đích
}
Cũng kiểm tra execution policy. PowerShell có thể âm thầm chặn script mà không in ra bất kỳ thông báo hữu ích nào:
# Xem policy được đặt ở từng scope:
Get-ExecutionPolicy -List
# Luôn truyền -ExecutionPolicy Bypass trong action của task:
powershell.exe -ExecutionPolicy Bypass -NonInteractive -File "C:\Scripts\run.ps1"
Chẩn Đoán Nhanh Qua schtasks
# Kết quả lần chạy cuối của mọi task trên máy:
schtasks /query /fo LIST /v | findstr /i "last run result"
# Xem chi tiết một task cụ thể:
schtasks /query /tn "\MyFolder\MyTask" /fo LIST /v
# Kích hoạt task ngay bây giờ để test:
schtasks /run /tn "\MyFolder\MyTask"
Xác Nhận Đã Sửa Xong
- Chuột phải vào task → Run
- Refresh Task Scheduler — Last Run Result phải hiển thị
0x0 - Mở file log và xác nhận output thực tế
- Event Viewer → TaskScheduler/Operational → event ID 201, result 0
# Kiểm tra nhanh từ PowerShell:
(Get-ScheduledTaskInfo -TaskName "YourTaskName").LastTaskResult
# Kết quả phải là: 0
Nguyên Nhân Thường Gặp Tổng Hợp
- Sai thư mục làm việc — đường dẫn tương đối thất bại khi khởi chạy từ System32
- Thiếu quyền — cần quyền admin hoặc truy cập mạng mà không có
- Script bị lỗi — thoát với exit code khác 0, Task Scheduler chỉ báo cáo lại trung thực
- Execution policy — PowerShell âm thầm chặn script
- Tiến trình cũ bị treo (0x41301) — không có timeout, các instance chồng chất lên nhau
- Thiếu dependency — script gọi Python, Node, hoặc công cụ khác chưa được cài đặt

