−25%

على الدفع السنوي لـ Windows حتى 31 أكتوبر. عرض الخطط

EQVPS
ابدأ الآن

كيف تشغّل سكربتاً على مدار الساعة في Windows Server: يصمد أمام تسجيل الخروج والأعطال وإعادة التشغيل

أبقِ روبوتاً أو سكربتاً يعمل ليلاً ونهاراً على VPS بنظام Windows Server 2022 باستخدام Task Scheduler وحده: يبدأ مع الإقلاع دون دخول أحد، ويعود خلال دقيقة بعد العطل، ولا تعمل منه نسختان أبداً. أوقفنا العملية بالقوة وأعدنا تشغيل الخادم للتحقق.

الطريقة المعتادة لتشغيل روبوت على VPS بنظام Windows هي تشغيله في جلسة RDP ثم إغلاق النافذة. ينجح ذلك حتى يعيد تحديثٌ تشغيل الخادم في الثالثة فجراً ولا يشغّله أحد من جديد. يحل Task Scheduler، الموجود في كل Windows Server، هذه المشكلة دون برامج إضافية. الإعداد أدناه:

  • يشغّل السكربت عند الإقلاع، قبل أن يسجّل أحد الدخول؛
  • يعيد تشغيله خلال دقيقة إذا تعطّل أو أُوقف؛
  • لا يشغّل نسختين في الوقت نفسه أبداً.

اختبرنا الأمور الثلاثة على صورة Windows Server 2022 لدينا: أوقفنا العملية، وأعدنا تشغيل الخادم، وعددنا النسخ.

السكربت التجريبي

بديل لروبوتك: يكتب سطراً كل 10 ثوانٍ، فيسهل أن ترى إن كان حياً.

New-Item -ItemType Directory -Force C:\bots | Out-Null
Set-Content C:\bots\heartbeat.ps1 -Encoding ascii -Value @'
while ($true) {
    Add-Content -Path C:\bots\heartbeat.log -Value ("{0:u} pid {1}" -f (Get-Date), $PID)
    Start-Sleep -Seconds 10
}
'@

سجّل المهمة

شغّل في PowerShell بصلاحيات المسؤول:

$action   = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument '-NoProfile -ExecutionPolicy Bypass -File C:\bots\heartbeat.ps1' -WorkingDirectory 'C:\bots'
$atBoot   = New-ScheduledTaskTrigger -AtStartup
$everyMin = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 1)
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) -MultipleInstances IgnoreNew -StartWhenAvailable
Register-ScheduledTask -TaskName 'mybot' -Action $action -Trigger $atBoot, $everyMin -Settings $settings -User 'SYSTEM' -RunLevel Highest
Start-ScheduledTask -TaskName 'mybot'

ما يفعله كل جزء:

  • -AtStartup يشغّل الروبوت عند إقلاع Windows، دون مستخدم مسجّل الدخول.
  • التكرار كل دقيقة يعيد تشغيل المهمة كل دقيقة. إذا كان الروبوت حياً لا يحدث شيء؛ وإذا توقف يبدأ من جديد.
  • -MultipleInstances IgnoreNew يجعل التكرار آمناً: أي تشغيل يجد الروبوت يعمل أصلاً يُتخطّى.
  • -ExecutionTimeLimit 0 يلغي الحد الافتراضي البالغ 72 ساعة، الذي كان Task Scheduler سيوقف الروبوت بعده.
  • -User 'SYSTEM' يشغّله دون كلمة مرور ودون جلسة. لحساب SYSTEM صلاحيات كاملة على الخادم، فلا تشغّل بهذه الطريقة إلا شيفرتك.

لـ Python استبدل الإجراء:

$action = New-ScheduledTaskAction -Execute 'C:\Program Files\Python312\python.exe' -Argument 'C:\bots\bot.py' -WorkingDirectory 'C:\bots'

ما الذي تحققنا منه

العطل. أوقفنا عملية الروبوت بـ Stop-Process -Force. بعد 46 ثانية كان المشغّل الدقيقي قد شغّل عملية جديدة، وكانت هناك نسخة واحدة بالضبط.

إعادة التشغيل. أعدنا تشغيل الخادم ولم نسجّل الدخول. بعد 40 ثانية من الإقلاع كان الروبوت يكتب في سجله، دون أي جلسات مستخدمين على الخادم.

ما لم ينجح. شيئان يبدوان صحيحين وليسا كذلك:

  1. «إذا فشلت المهمة، أعد التشغيل كل…». فعّلناه وأوقفنا العملية، فبقيت المهمة دقائق في حالة Ready. إنه يستجيب لمهمة تعجز عن البدء، لا لبرنامج يتوقف لاحقاً.
  2. حلقة التغليف (while ($true) { & bot; sleep 5 }). تعيد تشغيل روبوت متعطل، لكن إذا توقف الغلاف نفسه تستمر العملية الفرعية، ويشغّل التشغيل التالي روبوتاً ثانياً. انتهى بنا الأمر إلى نسختين، وهذا يعني لروبوت Telegram عمليتين تتنازعان التحديثات نفسها.

كيف تتحقق

Get-ScheduledTask -TaskName mybot | Select-Object TaskName, State
Get-ScheduledTaskInfo -TaskName mybot | Select-Object LastRunTime, NextRunTime
Get-Content C:\bots\heartbeat.log -Tail 5

لإيقافه أثناء الصيانة شغّل أولاً Disable-ScheduledTask mybot (وإلا أعاد المشغّل الدقيقي تشغيله)، ثم أوقف العملية. يعيده Enable-ScheduledTask mybot.

السجلات

لا تلتقط المهمة المخرجات. دع الروبوت يكتب سجله بنفسه كما في المثال، أو أعد توجيه المخرجات في ملف تشغيل صغير بامتداد .cmd ووجّه -Execute إليه.

أي خطة

روبوت PowerShell أو Python يستهلك قليلاً من المعالج، لكن Windows نفسه يشغل في صورتنا ما بين 1 و1.3 GB من الذاكرة وهو خامل. Windows-Small (4 vCPU و4 GB ذاكرة و50 GB، $11 شهرياً) هو الحجم المناسب لروبوت أو اثنين. في خطة NAT تعمل الاتصالات الصادرة (Telegram وواجهات المنصات البرمجية وwebhooks التي تستدعيها) كالمعتاد. إذا كان على الروبوت أن يستقبل webhooks أو حركة واردة أخرى، فاختر Windows Small-IP ($28 شهرياً) مع IPv4 خاص.

الخطوات التالية: أمّن RDP، وإن فضّلت إدارة الروبوت عبر SSH، ثبّت OpenSSH. الدفع بـ USDT أو USDC أو ETH، وWindows هنا هو Server 2022 بترخيصك الخاص (BYOL). كل الخطط: Windows VPS.

الأسئلة الشائعة

لماذا لا أترك السكربت يعمل في جلسة RDP الخاصة بي؟

يعمل ذلك حتى يُنهي شيءٌ الجلسة: تسجيل الخروج، أو إعادة التشغيل بعد التحديثات، أو عطل. إغلاق نافذة RDP (قطع الاتصال) يُبقي الجلسة حية، لكن تسجيل الخروج يُنهي كل ما فيها، وبعد إعادة التشغيل لا أحد مسجّل الدخول ليشغّله من جديد. المهمة المجدولة لا تعتمد على أي جلسة.

أليس في Task Scheduler خيار «أعد التشغيل عند الفشل»؟

بلى، لكنه لم يساعد في اختبارنا. حين أوقفنا عملية السكربت انتقلت المهمة إلى حالة «Ready» وبقيت فيها. هذا الخيار يستجيب حين تعجز المهمة عن البدء، لا حين يتوقف برنامجك لاحقاً. ما يعيده هو المشغّل المتكرر في هذا الدليل.

هل يمكن أن تعمل نسختان من الروبوت؟

ليس مع هذا الإعداد. تشغّل المهمة الروبوت نفسه (دون سكربت تغليف) وتستخدم MultipleInstances IgnoreNew، فلا يفعل المشغّل الدقيقي شيئاً ما دام الروبوت حياً. ما يصنع التكرار هو حلقة التغليف تحديداً: أوقف الغلاف فتستمر عمليته الفرعية، ويشغّل غلاف جديد نسخة أخرى. رأينا ذلك بالضبط.

هل يعمل هذا مع Python أو Node.js؟

نعم. ضع المفسّر في -Execute والسكربت في -Argument بمسارات كاملة، مثلاً -Execute 'C:\Program Files\Python312\python.exe' -Argument 'C:\bots\bot.py'. ثبّت المفسّر لكل المستخدمين كي يجده حساب SYSTEM.

التعليقات

لا تعليقات بعد. كن الأول.

اترك تعليقًا

تُراجَع التعليقات قبل ظهورها.