مرجع

مرجع سطر الأوامر

كل أمر وكل خيار وكل رمز خروج في bws، الإصدار 0.5.0. والأمر bws --help هو المرجع المعتمد وهو أطول، وهذه الصفحة هي السطح نفسه مرتبًا ليُقرأ.

الأوامر

أحد عشر أمرًا. snapshot اسم ويأخذ بعده كلمة. وtool اسم أيضًا، وحده يسرد الأدوات.

bws list [--query TEXT] [--signatures] [--memory] [--required-by] [--follow-network] [--json] [--timing]
bws show NAME [--full] [--follow-network] [--json] [--timing]
bws stop|start|restart NAME [--dry-run] [--dependents] [--timeout SECONDS] [--json] [--timing]
bws kill NAME [--force] [--restart] [--dry-run] [--dependents] [--timeout SECONDS] [--json] [--timing]
bws start-type NAME automatic|delayed|manual|disabled [--stop] [--dry-run] [--json] [--timing]
bws snapshot create [FILE] [--note TEXT] [--follow-network] [--force] [--json] [--timing]
bws snapshot diff EARLIER LATER [--exit-code] [--json] [--timing]
bws snapshot diff EARLIER --live [--exit-code] [--json] [--timing]
bws history [NAME] [--json] [--timing]
bws tool
bws tool fix
bws tool fix NAME [--dry-run] [--timeout SECONDS] [--json] [--timing]
bws license [--components]
bws --help
bws --version

الأمر الذي يُكتب بخطأ يُقترح عليه ما قصدته غالبًا، وينتهي التشغيل بالرمز 2 بدل أن يفعل شيئًا قريبًا مما طلبت.

$ bws lst
There is no command lst. Did you mean list?

ما يفعله كل أمر

list وshow

list هو الجهاز كله، مضيَّقًا بالخيار --query. وshow عنصر واحد مع كل ما هو معروف عنه: التوقيع والامتيازات، وكذلك security descriptor والذاكرة، وكلها تُقرأ في كل مرة، لأن ذلك يكلّف نحو ستين ميلي ثانية على عنصر واحد بينما يكلّف ثانية على الجهاز كله. والحقول الفارغة فعلًا تُترك ما لم تمرر --full. أما الحقل الذي لم يستطع أحد قراءته فيُطبع في الحالتين، لأن تركه كان سيبدو جوابًا.

stop وstart وrestart

كل منها يبني خطة وينفّذها. و--dry-run يطبع الخطة ولا يغيّر شيئًا، و--dependents يضع فيها الخدمات التي ستتعطل خطوات قائمة بذاتها، و--timeout يحدد كم تستطيع خطوة أن تمضي دون تقدم. وتُرفض برامج التشغيل ولا تُجرَّب، لأن إيقاف برنامج تشغيل في النواة كثيرًا ما لا يمكن التراجع عنه دون إعادة تشغيل.

kill: لخدمة لا تتوقف

يطلب من الخدمة أن تتوقف وينهي العملية الواقفة خلفها فقط إذا لم ينجح ذلك، فالعنصر الذي يتوقف من تلقاء نفسه لا يُنهى أبدًا. وإنهاء عملية يأخذ معه كل خدمة أخرى تعيش فيها، سواء توقفت قبل ذلك أم لا، وتسمّيها المعاينة وتسمّي العملية برقمها. و--force يتخطى الخطوة المهذبة وحينها تعرض المعاينة خطوة واحدة بدل اثنتين. و--restart يعيد كل شيء بعد ذلك.

يكتب Windows هذه الفكرة بشكل مختلف. الخيار --force في Stop-Service يعني «حتى لو كان شيء يعتمد عليها»، وهذا ما يفعله --dependents هنا. ولهذا فهو أمر قائم بذاته وليس خيارًا في stop.

start-type: إعداد وليس حركة

يحدد ما سيفعله المدير بعنصر عند الإقلاع التالي، ومن دون --stop لا يحرّك شيئًا: العنصر الذي يعمل يظل يعمل، والذي توقف يبقى متوقفًا، وتقول الخطة ذلك. وdisabled هو الذي يستحق التوقف عنده، لأنه يمنع المدير من بدء العنصر أصلًا، بما في ذلك عند الطلب لصالح شيء آخر يحتاج إليه. وdelayed تلقائي يبدأ بعد العناصر التلقائية الأخرى بقليل، وهو الكلمة التي يسأل عنها start:delayed في الاستعلام، ويرفضه Windows لعنصر في مجموعة ترتيب تحميل، وهذا تقوله الخطة قبل أن يحدث أي شيء. وكل من الأربعة يكتب هل يبدأ العنصر متأخرًا، كما يفعل sc.exe. و--stop، بجانب disabled وحده، يوقف العنصر في الخطة نفسها بعد كتابة الإعداد.

snapshot create وsnapshot diff

create يقرأ التوقيعات وقيم التجزئة دائمًا، لأن اللقطة تُحفظ وتُقارن لاحقًا، واللقطة الخالية منها تُقارن بلقطة فيها كأن الجهاز تغيّر. وdiff يقول ما تغيّر بالانتقال من الملف الأول إلى الثاني، أو من ملف إلى هذا الجهاز بالخيار --live. وفي صفحة اللقطات الصيغة والتعليل.

history: من غيّره، من سجل System

تغييرات نوع بدء التشغيل وعمليات التثبيت من سجل System، الأحدث أولًا، مع الحساب الذي سجّله Windows. ويقول السطر الأول إلى أي مدى يمتد السجل إلى الوراء وهل مُسح، لأن التاريخ لا يطول أكثر من السجل. ومع اسم تكون التغييرات في نوع بدء تشغيل تلك الخدمة، أما عمليات التثبيت فتُسرد دون اسم فقط، لأن Windows يسجّل التثبيت تحت الاسم المعروض لا اسم الخدمة أبدًا. ويُسمّى الحساب حيث يستطيع هذا الجهاز تسميته بنفسه ويُعرض بمعرّف SID خلاف ذلك، وتأتي أنواع بدء التشغيل بالكلمات التي كتبها Windows.

tool: إجابات جاهزة عن المشكلات الشائعة

الأدوات نفسها التي تعرضها النافذة في تبويب Tools. الأمر bws tool يسردها وbws tool fix يسرد الإصلاحات السريعة: printer وsound وindexing وsearch، وكل منها إعادة تشغيل خدمة Windows واحدة مع ما يعتمد عليها، اختيرت لأن صفحات استكشاف الأخطاء الرسمية من Microsoft تقترحها. والأمر bws tool fix printer هو بالضبط bws restart Spooler --dependents: الخطة نفسها والمخرجات نفسها ورموز الخروج نفسها، ومثل كل أمر هنا يغيّر شيئًا فهو لا يسأل أولًا، لذا فإن --dry-run هو طريقة النظر قبل أن يعمل.

license: ما بداخل الملف الذي نزّلته

لا يقرأ شيئًا إطلاقًا، لا مدير الخدمات ولا القرص ولا الشبكة، ويجيب من سجل مُجمَّع داخل الملف التنفيذي. و--components يحوّل الإشعار إلى كل مكوّن مع إصداره وترخيصه ومصدره. وهي المجموعة نفسها التي تحملها قائمة المواد المنشورة بجانب التنزيل، لأن الاثنتين تُولَّدان من سجل واحد، وهذا سبب أهميتها: البرنامج ملف واحد قائم بذاته، فلا يوجد بجانبه شيء ليقرأه الماسح.

أمثلة

فُحصت الخطط أدناه بالخيار --dry-run مقابل البرنامج الذي تصفه هذه الصفحة. والأمر الذي يغيّر شيئًا لا يسأل أولًا، لذا فإن --dry-run هو طريقة النظر قبل أن يعمل. وSpooler يقوم مقام أي خدمة، فضع اسم خدمتك مكانه.

ابحث واقرأ

bws list                                       كل خدمة وبرنامج تشغيل على هذا الجهاز
bws list --query "start:auto !status:running"  ما يجب أن يعمل ولا يعمل
bws list --query "status:running" --memory     ما تستخدمه عملية كل عنصر يعمل
bws show Spooler                               كل ما هو معروف عن عنصر واحد
bws show Spooler --full                        وكذلك الحقول الفارغة فعلًا

انظر أولًا، ثم غيّر

bws restart Spooler --dry-run                الخطة، ولا شيء غيرها
bws restart Spooler --dependents             أعد تشغيلها مع ما يعتمد عليها
bws stop Spooler --dependents --timeout 120  اسمح بدقيقتين لكل خطوة دون تقدم
bws start-type WSearch delayed --dry-run     ابدأها بعد العناصر التلقائية الأخرى بقليل
bws start-type Spooler disabled --stop       عطّلها وأوقفها في خطة واحدة

خدمة لا تتوقف

bws kill Spooler --dry-run          العملية، وكل خدمة تعيش فيها
bws kill Spooler --restart          أنهِ العملية فقط إذا فشل الإيقاف، ثم أعد كل شيء
bws kill Spooler --force --dry-run  خطوة واحدة بدل اثنتين: تُنهى العملية فورًا

اللقطات والانحراف

bws snapshot create before.json --note "before the patch"  جمّد الجهاز، مع ملاحظة تُحفظ بداخله
bws snapshot diff before.json after.json                   ملفان: يومان، أو جهازان
bws snapshot diff before.json --live                       الملف مقابل هذا الجهاز كما هو الآن
bws snapshot diff before.json --live --exit-code           الأمر نفسه، وينتهي بالرمز 5 إذا انحرف التكوين

من غيّره

bws history          كل تغيير في نوع بدء التشغيل وكل تثبيت يحتفظ به سجل System
bws history Spooler  تغييرات نوع بدء تشغيل خدمة واحدة
bws history --json   الشيء نفسه مستندًا، مع السجل والتغييرات

إصلاحات سريعة

bws tool                      الأدوات الموجودة
bws tool fix                  الإصلاحات السريعة، والخدمة خلف كل واحد
bws tool fix sound --dry-run  خطة إعادة تشغيل خدمتي الصوت
bws tool fix printer          أعد تشغيل Print Spooler مع ما يعتمد عليها

ما بداخل الملف

bws license --components  كل مكوّن وإصداره وترخيصه ومصدره
bws --version             إصدار هذا الملف التنفيذي

في سكربت PowerShell

# العناصر التي يجب أن تعمل ولا تعمل، ككائنات
bws list --query "start:auto !status:running" --json | ConvertFrom-Json | Select-Object serviceName, displayName, status

# الملفات غير الموقّعة، في جدول بيانات
bws list --query "signed:no" --json | ConvertFrom-Json | Select-Object serviceName, binaryPath | Export-Csv unsigned.csv -NoTypeInformation

# ما تحتاجه خدمة واحدة
(bws show Spooler --json | ConvertFrom-Json).dependsOn

# فحص ليلي يتفرع بحسب رمز الخروج
bws snapshot diff C:\baselines\web01.json --live --exit-code > $null
switch ($LASTEXITCODE) {
  0 { 'no configuration drift' }
  5 { 'the configuration drifted' }
  default { "no clean answer, exit code $LASTEXITCODE" }
}

في cmd وملف دفعي

rem أمر ثانٍ فقط إذا لم ينتهِ الأول نظيفًا
bws restart Spooler || echo the restart did not end cleanly

rem في ملف دفعي مفعّل فيه التوسع المتأخر يحتاج الرمز ! إلى علامة ^
bws list --query "start:auto ^!status:running"

الخيارات

18 منها. والعمود الثالث هو الأوامر التي ينتمي إليها كل خيار: فالخيار الممرَّر إلى أمر لا فائدة له فيه خطأ ومعه تلك القائمة، وليس خيارًا يُتجاهل بصمت.

الخيارما يفعلهأين يعمل
--queryضيّق القائمة بلغة الاستعلام.list
--signaturesاقرأ من وقّع كل ملف تنفيذي وهل يثق به Windows. يستغرق ذلك عدة ثوانٍ على جهاز كامل، لذا هو معطّل ما لم يُطلب، والاستعلام عن التوقيعات يشغّله من تلقاء نفسه.list
--memoryاقرأ ما تستخدمه عملية كل عنصر يعمل. معطّل افتراضيًا لأنه قياس وليس إعدادًا: فهو يختلف بعد ثانية.list
--required-byاقرأ العناصر التي تتعطل إن أُوقف عنصر ما، يُسأل Windows عنها مباشرة بدل استنتاجها مما يعلنه كل شيء. نداء واحد لكل عنصر، لذا هو معطّل ما لم يُطلب. وshow وsnapshot create يقرآنه في كل مرة.list
--follow-networkدع الأداة تصل إلى خارج هذا الجهاز أصلًا: مسار تشغيل يقع على مشاركة شخص آخر، وشهادة لا يحملها هذا الجهاز أصلًا. معطّل افتراضيًا للأمان: فمشاركة واحدة لا يمكن الوصول إليها تكلّف إحدى وعشرين ثانية وتُصادَق باسم من شغّلها، وجلب شهادة اتصال بطرف ثالث في منتصف قائمة عادية. وبدونه يُفحص التوقيع مقابل ما هو موجود هنا، والنتيجة التي ربما سببها عدم النظر تُبلَّغ على أنها غير مقروءة لا على أنها حكم.list, show, snapshot create
--forceفي kill، أنهِ العملية فورًا دون أن تسأل بلطف، فتعرض المعاينة خطوة واحدة بدل اثنتين. وفي snapshot create، استبدل لقطة موجودة بالفعل، ولا يُستبدل ملف ليس لقطة أبدًا.snapshot create, kill
--restartفي kill، أعد العنصر بعد ذهاب العملية، مع كل ما كان يشاركها.kill
--stopفي start-type، ومع disabled وحده، أوقف العنصر في الخطة نفسها بعد كتابة الإعداد. فنوع بدء التشغيل يغيّر الإقلاع التالي ولا يغيّر شيئًا الآن، لذا فبدونه يظل عنصر يعمل ومضبوط على disabled يعمل.start-type
--fullفي show، اطبع أيضًا الحقول الفارغة فعلًا. والحقل الذي لم يستطع أحد قراءته يُطبع في الحالتين.show
--jsonالمستند نفسه، مقروءًا للآلة، على الإخراج القياسي.list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME
--noteما أُخذت اللقطة من أجله، محفوظًا داخل الملف.snapshot create
--exit-codeانتهِ بالرمز 5 عندما يختلف التكوين: عنصر أُضيف أو أُزيل، أو عنصر مضبوط بشكل مختلف. وحالة التشغيل وحدها لا تُحتسب. معطّل افتراضيًا، حتى لا يتعثر سكربت يريد طباعة الفروق فقط حين يجد بعضها.snapshot diff
--liveقارن الملف بهذا الجهاز كما هو الآن، بدل مقارنته بملف ثانٍ.snapshot diff
--timingكم استغرق كل جزء من القراءة، على الخطأ القياسي.list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME
--dry-runاطبع الخطة ولا تغيّر شيئًا. هي الخطة نفسها التي يشغّلها التنفيذ: لا يوجد مسار برمجي ثانٍ للتنفيذ الفعلي.stop, start, restart, start-type, kill, tool fix NAME
--dependentsضع الخدمات التي ستتعطل في الخطة خطوات قائمة بذاتها.stop, restart, kill
--timeoutكم يمكن لخطوة واحدة أن تمضي دون تقدم قبل أن يُتخلى عنها، ويُعاد العدّ كلما أبلغت الخدمة عن تقدم. ستون ثانية ما لم تقل غير ذلك. والخدمة التي تواصل الإبلاغ عن تقدم تبقى مراقبة ما دام ذلك لازمًا. وانتهاء المهلة هو نهاية المراقبة لا فشل، ويقول التقرير أين تُرك العنصر.stop, start, restart, kill, tool fix NAME
--componentsفي license، حوّل الإشعار إلى كل مكوّن داخل هذا الملف التنفيذي مع إصداره وترخيصه ومصدره. وهي المجموعة نفسها التي تحملها قائمة المواد المنشورة بجانب التنزيل، لأن الاثنتين تُولَّدان من سجل واحد.license

رموز الخروج

6 نهايات، وكل واحدة منها شيء مختلف يفعله السكربت. تذهب البيانات إلى الإخراج القياسي وكل ما عداها إلى الخطأ القياسي، فيعمل bws list --json | jq ولا يصل تحذير إلى JSON أبدًا.

كل مستند JSON هو ASCII عادي: الحرف الخارج عنه يُكتب هروبًا من ستة محارف يعيده كل قارئ JSON إلى الحرف، فالأمر bws list --json > file.json ينتج UTF-8 صالحًا و| ConvertFrom-Json يقرؤه صحيحًا أيًا كانت صفحة الرموز المضبوطة للطرفية. وفي النص الذي يقرؤه الشخص يُعرض المحرف الذي كان سيحرّك الطرفية بدل أن يُطبع، أي علامة جدولة أو فاصل سطر أو متتالية هروب أو تجاوز للاتجاه، برقم رمزه، <U+001B>.

الرمز -- ينهي الخيارات، فتستطيع تسمية خدمة يبدأ اسمها بشرطة: bws show -- -odd. وأسطر الأوامر التي تسلّمها لك الأداة مكتوبة لبيئة PowerShell: الاسم الذي فيه مسافة يوضع بين علامتي اقتباس مزدوجتين، ويقرؤها cmd بالطريقة نفسها، والاسم الذي كان PowerShell سيوسّعه داخلها، مثل MSSQL$SQLEXPRESS، يوضع بين علامتي اقتباس مفردتين.

الرمزالمعنى
0تم، ووصل كل شيء إلى حيث كان ذاهبًا.
1فشلت الأداة: لم تستطع فعل ما طُلب، لسبب يتعلق بالأداة لا بالخطة.
2كان سطر الأوامر خاطئًا. والأمر الذي يُكتب بخطأ يُقترح عليه ما قصدته غالبًا.
3كانت الخطة سليمة، وعملت، وشيء فيها لم يصل إلى حيث كان ذاهبًا: رفض المدير، أو لم تملك الجلسة الصلاحيات عليه.
4أوقف شخص التشغيل بيده. رمز غير صفري حتى لو وصلت كل الخطوات، حتى لا يعامل أي غلاف برمجي التشغيل المقطوع على أنه نظيف.
5جرت مقارنة ووجدت أن التكوين انحرف: عنصر أُضيف أو أُزيل، أو عنصر مضبوط بشكل مختلف. وحالة التشغيل وحدها ليست انحرافًا. وذلك فقط مع --exit-code، لأن الانحراف هو ما صُنعت هذه الأداة لإيجاده، وإيجاده ليس فشلًا.

الضغط على Ctrl+C له ثلاثة مستويات، وكل مستوى يقول كم يكلّف التالي. الأول يتوقف عن المضي قدمًا ويعيد مع ذلك ما أُخذ، والثاني يترك الأمور كما هي ويطبع التقرير مع ذلك، والثالث ينهي العملية. والتشغيل الذي يوقفه شخص بيده ينتهي بالرمز 4 حتى لو وصلت كل الخطوات.

إغلاق نافذة وحدة التحكم يُحتسب كأول Ctrl+C. يمهل Windows البرنامج خمس ثوانٍ بعد ذلك، وفيها يتوقف هذا البرنامج عن المضي قدمًا ويعيد ما أوقفه. أما تسجيل الخروج والإيقاف فينهيانه دون أي تحذير يمكنه التصرف بناءً عليه، وقد تفعل ذلك أيضًا جلسة بعيدة انقطعت.

في مهمة مجدولة

الشكل الذي بُنيت هذه الأداة له: جمّد الجهاز وهو سليم معروف، ثم اسأل كل ليلة هل ما زال كذلك.

# يوم يدخل الجهاز الخدمة
bws snapshot create C:\baselines\web01.json --note "after the build"

# كل ليلة، من مهمة مجدولة
bws snapshot diff C:\baselines\web01.json --live --exit-code --json > C:\logs\drift.json
#   0 - لا انحراف في التكوين
#   5 - انحرف التكوين، ويقول drift.json ما الذي حدث
#   3 - عمل ولم يستطع قراءة كل شيء، فالجواب جزئي

النافذة هي النصف الآخر من المحرك نفسه: BetterWindowsServices-win-x64.zip يحملها، وصفحة التنزيل تقول ما هو كل أرشيف.

وسيط النافذة

BetterWindowsServices.exe يأخذ وسيطًا واحدًا مخصصًا لشخص: --catalogue يفتح ورقة للمطوّر تعرض كل مكوّن في النافذة في كل حالة، ولا يقرأ شيئًا من جهازك. والوسيط الثاني، --carry، هو الطريقة التي تسلّم بها نافذة ما كانت تعرضه إلى نسختها التي تعيد تشغيلها بصفة مسؤول. لا أحد يكتبه، وأي شيء فيه لم تكن تلك النافذة لتكتبه يُرفض.