Task Scheduler در ویندوز: زمانبندی کارها بدون سرویس دستی
چگونه با Task Scheduler و schtasks کارهای تکراری، بکاپ و اسکریپت PowerShell را زمانبندی کنید؛ Trigger، Action و اشتباههای رایج.
Founder & product engineer

هر تیمی که روی ویندوز کار میکند دیر یا زود به کاری میرسد که باید بدون حضور انسان اجرا شود: پاکسازی لاگ، بکاپ پوشهٔ پروژه، اجرای اسکریپت مهاجرت در نیمهشب، یا گزارش وضعیت سرویس. اگر برای هر مورد یک Windows Service بنویسید، هزینهٔ نگهداری و مجوز بالا میرود. Task Scheduler (زمانبند وظایف) همان لایهٔ رسمی ویندوز برای اجرای برنامهها و اسکریپتها بر اساس زمان، رویداد یا وضعیت سیستم است.
این مقاله مفهوم Trigger و Action، تفاوت اجرا با حساب کاربر در برابر SYSTEM، کار با رابط گرافیکی و schtasks، و الگوهای امن برای توسعهدهنده را پوشش میدهد — نه فقط «یک تسک بسازید و تمام».

پاسخ کوتاه
Task Scheduler سرویس داخلی ویندوز است که تعریف وظیفه (Task) را نگه میدارد و وقتی شرط Trigger برقرار شد، Action را اجرا میکند. برای کار روزمره: `taskschd.msc` را باز کنید یا با `schtasks` از خط فرمان بسازید. برای اسکریپت PowerShell مسیر کامل `powershell.exe` یا `pwsh.exe` را با آرگومان `-File` بگذارید، حساب اجرا و «Run whether user is logged on or not» را آگاهانه انتخاب کنید، و همیشه لاگ خروج و Last Result را بعد از اولین اجرا چک کنید.
زمانبندی موفق یعنی Trigger درست + مسیر مطلق + حساب با کمترین مجوز لازم + مشاهدهٔ نتیجه — نه فقط دکمهٔ OK.
مسئلهای که Task Scheduler حل میکند
سه الگوی تکراری در تیمهای نرمافزاری:
- کارهای نگهداری محلی روی لپتاپ یا سرور ویندوز که نباید وابسته به باز بودن ترمینال باشند.
- اجرای دورهای ابزارهایی که سرویس دائمی نیستند (مثل اسکریپت پاکسازی cache بیلد).
- واکنش به رویداد سیستم؛ مثلاً بعد از لاگین یا هنگام بیکاری سیستم.
جایگزین خام این است که پنجرهٔ PowerShell باز بماند یا از ابزار شخص ثالث استفاده کنید. Task Scheduler یکپارچه با Event Log، سیاست گروه و حسابهای دامنه است و روی همهٔ نسخههای مدرن ویندوز در دسترس است.
اجزای یک Task
Trigger
شرط شروع: یکبار در زمان مشخص، روزانه/هفتگی، هنگام Startup، هنگام Log on، هنگام Idle، یا روی رویداد Event Log. میتوانید چند Trigger برای یک Task داشته باشید. برای CI محلی سبک، Daily در ساعت کمترافیک رایج است؛ برای ابزار توسعهٔ شخصی، At log on مفیدتر است.
Action
معمولاً Start a program: مسیر اجرایی + آرگومان + Start in (پوشهٔ کاری). ارسال ایمیل و نمایش پیام در نسخههای جدیدتر محدود یا منسوخ شدهاند؛ برای اعلان بهتر است خود اسکریپت لاگ بنویسد یا به کانال مانیتورینگ بفرستد.
Conditions و Settings
شرایطی مثل «فقط روی برق شهری»، «فقط اگر شبکه در دسترس است»، و تنظیماتی مثل توقف پس از X ساعت، راهاندازی مجدد در صورت شکست، یا اجازهٔ اجرای موازی. روی لپتاپ توسعهدهنده، شرط باتری اغلب باعث «چرا اجرا نشد؟» میشود.
ساخت سریع از رابط گرافیکی
- Win+R بزنید و taskschd.msc را اجرا کنید.
- Create Basic Task یا Create Task (کنترل بیشتر) را انتخاب کنید.
- نام معنادار بگذارید؛ مثلاً Dev-Cleanup-NodeModules نه Task1.
- Trigger و Action را تنظیم کنید؛ در Action مسیر کامل را وارد کنید.
- در تب General مشخص کنید با بالاترین سطح امتیاز اجرا شود یا نه، و آیا فقط وقتی کاربر وارد شده اجرا شود.
- با Run تسک را یکبار دستی اجرا و History/Last Run Result را ببینید.
اگر History خالی است، در Action منوی View گزینهٔ Show Hidden Tasks را چک کنید و در Task Scheduler Library روی Enable All Tasks History کلیک راست کنید (در نسخههایی که این گزینه موجود است).
اسکریپت PowerShell بهعنوان Action
اشتباه رایج: فقط مسیر فایل `.ps1` را در Program/script بگذارید. ویندوز باید میزبان را بداند:
text
Program/script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe Add arguments: -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\cleanup.ps1" Start in: C:\Scripts
برای PowerShell 7 مسیر معمولاً شبیه `C:\Program Files\PowerShell\7\pwsh.exe` است. `-NoProfile` از کندی و تداخل پروفایل جلوگیری میکند. ExecutionPolicy را در سطح سیستم شل نکنید مگر سیاست سازمان اجازه دهد؛ محدود کردن به همان آرگومان تسک امنتر است.
schtasks از خط فرمان
برای مستندسازی و استقرار تکرارپذیر، schtasks بهتر از کلیکهای GUI است:
powershell
schtasks /Create /TN "Dev\CleanupTemp" /TR "powershell.exe -NoProfile -File C:\Scripts\cleanup.ps1" /SC DAILY /ST 02:30 /RL LIMITED /F schtasks /Query /TN "Dev\CleanupTemp" /V /FO LIST schtasks /Run /TN "Dev\CleanupTemp" schtasks /End /TN "Dev\CleanupTemp" schtasks /Delete /TN "Dev\CleanupTemp" /F
`/RL HIGHEST` برای کارهای مدیریتی، `/RU` و `/RP` برای حساب مشخص. رمز را در اسکریپت خام ذخیره نکنید؛ در دامنه از Managed Service Account یا اجرای تعاملی یکباره برای ذخیرهٔ اعتبار استفاده کنید. مستندات رسمی schtasks در Microsoft Learn پارامترهای create/query/change را بهتفصیل دارد.
حساب اجرا: کاربر، SYSTEM یا سرویس
| حساب | چه وقت | ریسک |
|---|---|---|
| کاربر لاگینشده | ابزار UI یا دسترسی به پروفایل همان کاربر | با Log off متوقف میشود اگر فقط interactive باشد |
| کاربر با ذخیرهٔ رمز | اجرای پسزمینه بدون نشست | چرخش رمز دامنه تسک را میشکند |
| SYSTEM | نگهداری ماشین، دسترسی بالا | بیشمجوز؛ اشتباه اسکریپت خطرناک است |
| gMSA / سرویس دامنه | سرور سازمانی | نیاز به زیرساخت AD |
اصل کمینهٔ مجوز: اسکریپت پاکسازی پوشهٔ موقت توسعهدهنده نیازی به SYSTEM ندارد. برعکس، تسک تعمیر سرویس سطح ماشین ممکن است SYSTEM یا حساب ادمین محلی بخواهد.
مشاهدهٔ نتیجه و عیبیابی
- Last Run Result برابر 0x0 معمولاً موفقیت است؛ کدهای دیگر را با جدول HRESULT/Win32 تفسیر کنید.
- خروجی اسکریپت را به فایل Redirect کنید؛ Task Scheduler stdout را مثل ترمینال نشان نمیدهد.
- Event Viewer → Applications and Services Logs → Microsoft → Windows → TaskScheduler برای جزئیات.
- اگر «تسک اجرا شد ولی کاری نکرد»، Start in، مسیر نسبی، و متغیر محیطی متفاوت با نشست تعاملی را چک کنید.
powershell
powershell.exe -NoProfile -File C:\Scripts\cleanup.ps1 *>> C:\Scripts\logs\cleanup.log 2>&1
در خود اسکریپت هم `Start-Transcript` یا لاگ ساختاریافته کمک میکند. همبستگی زمان Last Run Time با لاگ اپ، حدس را کم میکند.
مقایسه با سرویس ویندوز و cron
سرویس برای فرایند همیشه-روشن با کنترل Start/Stop و بازیابی است. Task برای کار رویدادی یا دورهای است. اگر چیزی باید هر ۳۰ ثانیه یک سوکت گوش دهد، سرویس یا worker مناسبتر است؛ اگر هر شب یک گزارش بسازد، Task Scheduler.
روی لینوکس، cron/systemd timer نقش مشابه دارند. اگر تیم دوگانه دارید، منطق زمانبندی را در اسکریپت نگه دارید و فقط لایهٔ زمانبند را بومی کنید تا دو بار منطق کسبوکار ننویسید.
الگوی عملی: بکاپ پوشهٔ پروژه
- اسکریپت Compress-Archive یا robocopy را با مسیر مطلق بنویسید.
- پوشهٔ مقصد و نگهداری N نسخهٔ آخر را در اسکریپت کنترل کنید.
- تسک Daily بسازید؛ شرط شبکه را فقط اگر مقصد شبکهای است فعال کنید.
- یکبار با /Run تست کنید و حجم مقصد را ببینید.
- هشدار شکست را با بررسی Exit Code در اسکریپت و نوشتن Event یا فایل sentinel پیاده کنید.
powershell
$src = 'C:\Work\myapp' $dst = "D:\Backups\myapp-$(Get-Date -Format yyyyMMdd).zip" Compress-Archive -Path $src -DestinationPath $dst -Force if (-not (Test-Path $dst)) { exit 2 }
امنیت و اشتباههای رایج
- قرار دادن اسکریپت در پوشهٔ قابلنوشتن همگانی؛ مهاجم میتواند محتوا را عوض کند و Task با مجوز بالا اجرا کند.
- ExecutionPolicy Unrestricted سراسری بهجای Bypass فقط برای همان فراخوانی.
- فراموش کردن اینکه مسیرهای mapped drive در نشست غیرتعاملی ممکن است موجود نباشند؛ از UNC استفاده کنید.
- ساخت دهها Task بدون نامگذاری و پوشهبندی؛ بعد از شش ماه کسی جرئت حذف ندارد.
- اتکا به «Run with highest privileges» برای پنهان کردن مشکل مجوز بهجای درست کردن ACL.
- نبود مانیتورینگ Last Result؛ تسک ماهها با خطا اجرا میشود و کسی خبر ندارد.
چه وقت استفاده کنید / نکنید
استفاده کنید وقتی کار مرزی، تکرارپذیر و قابل بیان با Trigger است و نیاز به حضور دائم فرایند نیست. استفاده نکنید وقتی به صف پیام، هماهنگی توزیعشده، یا تضمین exactly-once در خوشه نیاز دارید — آنجا زمانبند سازمانی یا orchestration مناسبتر است. همچنین برای کارهای تعاملی UI که به دسکتاپ نشست خاصی وابستهاند، محدودیت session 0 isolation را بشناسید.
عمق عملیاتی بیشتر
توسعه روی ویندوز وقتی پایدار میشود که ابزار مشاهده، کنترل فرایند و زمانبندی را مثل مهارت کدنویسی جدی بگیرید.
بسیاری از اتلاف وقت روزانه نه از کمبود دانش زبان برنامهنویسی، بلکه از ندیدن مصرف حافظه، قفل فایل و سرویس خاموش است.
قبل از نصب ابزار شخص ثالث، قابلیت توکار ویندوز را امتحان کنید؛ مستندات Microsoft Learn معمولاً مسیر رسمی و پشتیبانیشده را نشان میدهد.
عادت کنید برای هر مشکل یک یادداشت کوتاه بنویسید: نشانه، زمان، PID، و فرمان یا ابزاری که استفاده کردید.
این یادداشتها در تیم به پایگاه دانش تبدیل میشوند و از تکرار دیباگ کور جلوگیری میکنند.
قدرت واقعی وقتی است که Task Manager، Resource Monitor، Event Viewer و PowerShell را در یک جریان واحد به کار ببرید.
اگر فقط یک پنجره را باز میکنید و حدس میزنید، همان چرخهٔ ریبوت بیدلیل تکرار میشود.
برای کارهای تکراری، بهجای حافظهٔ انسانی از Task Scheduler و اسکریپت نسخهٔکنترلشده استفاده کنید.
مجوز حداقل را رعایت کنید؛ اجرای همیشگی با Administrator ریشهٔ بسیاری از عادتهای ناامن است.
در نهایت، محیط توسعهٔ خوب آن است که شکست را سریع دیده، محدود و قابلبازگشت میکند — نه اینکه همه چیز را هر بار از صفر نصب کنید.
وقتی اپلیکیشن پاسخ نمیدهد، اول صبر کوتاه و مشاهدهٔ CPU و دیسک مفیدتر از End Task فوری است؛ شاید در حال نوشتن فایل یا انتظار شبکه باشد.
Analyze wait chain در Task Manager کمک میکند ببینید فرایند بهخاطر وابستگی به فرایند دیگر متوقف شده یا واقعاً حلقهٔ معیوب دارد.
Resource Monitor جزئیات دستهٔ دیسک و شبکه را نشان میدهد که در نمای سادهٔ Task Manager دیده نمیشود.
برای مصرف حافظه، تفاوت Working Set و Commit را بشناسید تا فقط با یک عدد بزرگ نترسید یا برعکس مشکل نشتی را نادیده نگیرید.
PowerShell با Get-Process و Get-Counter برای نمونهبرداری تکرارپذیر مناسب است و خروجیاش را میتوان لاگ کرد.
در محیط حرفهای، ریبوت باید آخرین گزینه باشد نه اولین Reflex؛ ریبوت علت را پاک میکند و یادگیری را میکشد.
ابزارهای عیبیابی توکار مثل Reliability History و Windows Memory Diagnostic برای الگوی زمانی خطا ارزش دارند.
اگر مشکل بعد از بهروزرسانی شروع شده، همبستگی تاریخ وصله با Event Log را قبل از بازنصب کامل بررسی کنید.
اسکریپتهای نگهداری را با مسیر مطلق و حساب کممجوز در Task Scheduler بگذارید و نتیجه را در فایل لاگ ببینید.
همکاری با تیم پشتیبانی وقتی سریع میشود که PID، نام دقیق فرایند، و اسکرین از Performance را ضمیمه کنید نه فقط «سیستم کند است».
ویندوز برای توسعهدهنده یک مانع نیست اگر لایهٔ مشاهده و کنترل را یاد بگیرید؛ همین مهارتها روی سرور ویندوزی هم برمیگردد.
از طرفی، وابستگی افراطی به GUI بدون فرمان خط فرمان، خودکارسازی و CI را ضعیف میکند.
تعادل سالم این است: GUI برای کشف، PowerShell برای تکرار، و مستندسازی برای تیم.
در پروژههای چندسیستمی، مرز واضح بین ابزار ویندوز و ابزار WSL از تداخل PATH و نسخههای تکراری جلوگیری میکند.
هر ماه یکبار فهرست سرویسهای غیرضروری استارتآپ و تسکهای زمانبندیشده را مرور کنید؛ رشد خاموش آنها منابع را میخورد.
نکتهٔ تکمیلی برای پایداری محیط این است که تغییرات سیستم را کوچک و قابلبرگشت نگه دارید و همیشه مسیر بازگشت داشته باشید.
قبل از تغییر سیاست اجرا یا نصب درایور آزمایشی، یک نقطهٔ بازیابی یا حداقل یادداشت نسخهٔ قبلی ابزارها تهیه کنید.
در دیباگ شبکهٔ محلی، ابتدا از localhost و سپس از نشانی واقعی استفاده کنید تا لایهٔ مشکل جدا شود.
برای کارهای فایل حجیم، بهجای کپی دستی تکراری از اسکریپت و لاگ استفاده کنید تا خطا قابلپیگیری باشد.
اگر ابزار توکار جواب نداد، آنگاه سراغ ابزار پیشرفتهتر بروید؛ ترتیب مهم است چون دادهٔ اولیه را از دست نمیدهید.
همین ترتیب را در تیم آموزش دهید تا نیروی تازهوارد هم از ریبوت اول شروع نکند.
در عمل، زنجیرهٔ عیبیابی خوب از مشاهدهٔ زنده شروع میشود، به لاگ تاریخی میرسد، و با یک تغییر کوچک قابلبرگشت ادامه پیدا میکند.
اگر در همان قدم اول نرمافزار را reinstall کنید، متغیرهای زیادی را همزمان جابهجا کردهاید و علت مبهم میماند.
برای توسعهدهنده، ثبت نسخهٔ ابزار، زمان وقوع و پیام خطا بخش از کار حرفهای است نه کار اضافی.
ویندوز وقتی پیشبینیپذیر میشود که سرویسها، تسکهای زمانبندی و استارتآپ را مثل inventory کد مدیریت کنید.
هر چه این inventory شفافتر باشد، اثر جانبی آپدیت و نصب پکیج جدید کمتر غافلگیرتان میکند.
همچنین برای کارهای خودکار، خروجی را به فایل یا رویداد بنویسید تا موفقیت خاموش با شکست خاموش اشتباه نشود.
این عادتها هزینهٔ اولیه دارند ولی در هفتههای پرترافیک بیلد و انتشار، زمان را برمیگردانند.
اگر تازهوارد تیم هستید، همین ابزارهای توکار را در روز اول با یک سناریوی ساختگی تمرین کنید تا در حادثه واقعی دستپاچه نشوید.
در محیطهایی که هم ویندوز و هم لینوکس دارید، یک فرهنگ مشترک برای نامبردن فرایند، پورت و زمان رویداد بسازید.
زبان مشترک عیبیابی، بیشتر از یکسانسازی سیستمعامل، همکاری را سریع میکند.
خلاصه
Task Scheduler لایهٔ استاندارد ویندوز برای اجرای زمانبندیشده است: Trigger شرط را میگوید، Action کار را انجام میدهد، حساب و Settings مرز امنیتی را تعیین میکنند. با مسیر مطلق، لاگ فایل، schtasks برای تکرارپذیری، و کمینهٔ مجوز، کارهای نگهداری را از «یادم باشد دستی بزنم» جدا کنید. برای مشاهدهٔ خطاها Event Viewer و History تسک را به عادت تبدیل کنید.
سوالات متداول
تفاوت Create Basic Task و Create Task چیست؟
Basic ویزارد سادهتر با گزینههای کمتر است. Create Task همهٔ تبها (Conditions، Settings، چند Action) را یکجا میدهد و برای کار حرفهای مناسبتر است.
چرا تسک روی لپتاپ اجرا نمیشود؟
اغلب شرط AC power، خواب سیستم (Sleep)، یا نبود نشست کاربر است. Settings مربوط به Wake و Conditions را بازبینی کنید و با schtasks /Run وقتی بیدار است تست کنید.
آیا میتوان از روی ریموت تسک ساخت؟
بله؛ schtasks از /S برای سیستم راه دور پشتیبانی میکند و MMC میتواند به کامپیوتر دیگر وصل شود، به شرط مجوز و فایروال مناسب.
Scheduled Jobs خود PowerShell چطور؟
ماژولهای قدیمی ScheduledJob روی Windows PowerShell وجود دارند ولی برای بسیاری سناریوها Task Scheduler + `-File` سادهتر و قابلمشاهدهتر در taskschd.msc است.
منابع و مراجع
- Using the Task Scheduler — Microsoft Learn: https://learn.microsoft.com/en-us/windows/win32/taskschd/using-the-task-scheduler
- Task Scheduler Reference — Microsoft Learn: https://learn.microsoft.com/en-us/windows/win32/taskschd/task-scheduler-reference
- schtasks commands — Microsoft Learn: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks
Author
Soheil Ebrahimpour is the founder of FutureForge. He works on product design, architecture, and getting custom software into production.
Related notes
If you are unsure about architecture or the build path, we can talk about the project.
Describe the problem and the constraints. If there is a fit, we will schedule a conversation.




