الصفحة الرئيسية » howto » كيفية استخدام ملف دفعي لجعل برامج نصية PowerShell أسهل لتشغيل

    كيفية استخدام ملف دفعي لجعل برامج نصية PowerShell أسهل لتشغيل

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

    لماذا لا يمكنني نسخ ملف .PS1 الخاص بي إلى كمبيوتر آخر وتشغيله?

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

    1. لا يرتبط PowerShell بملحق الملف .PS1 بشكل افتراضي.
      قدمنا ​​هذا في البداية في سلسلة دروس PowerShell Geek. يربط Windows ملفات .PS1 إلى المفكرة بشكل افتراضي ، بدلاً من إرسالها إلى مترجم أوامر PowerShell. هذا لمنع تنفيذ عرضي للنصوص الضارة عن طريق النقر المزدوج فوقها ببساطة. هناك طرق يمكنك من خلالها تغيير هذا السلوك ، ولكن ربما لا ترغب في القيام به على كل كمبيوتر تقوم بنقل البرامج النصية إليه - خاصة إذا كانت بعض هذه الأجهزة غير خاصة بك.
    2. لا يسمح PowerShell بتنفيذ البرنامج النصي الخارجي بشكل افتراضي.
      يمنع الإعداد ExecutionPolicy في PowerShell تنفيذ البرامج النصية الخارجية بشكل افتراضي في كافة إصدارات Windows. في بعض إصدارات Windows ، لا يسمح الإعداد الافتراضي بتنفيذ البرنامج النصي على الإطلاق. لقد أوضحنا لك كيفية تغيير هذا الإعداد في كيفية السماح بتنفيذ برامج نصية PowerShell على Windows 7. ومع ذلك ، فهذا أيضًا شيء لا تريد القيام به على أي جهاز كمبيوتر.
    3. لن تعمل بعض النصوص البرمجية لـ PowerShell بدون أذونات المسؤول.
      حتى مع تشغيل حساب على مستوى المسؤول ، ما زلت بحاجة إلى الحصول على التحكم في حساب المستخدم (UAC) لتنفيذ إجراءات معينة. لا نريد تعطيل هذا ، لكنه لا يزال لطيفًا عندما نتمكن من تسهيل التعامل معه.
    4. قد يكون لدى بعض المستخدمين بيئات PowerShell مخصصة.
      من المحتمل ألا تتعرض لهذا الأمر كثيرًا ، ولكن عندما تفعل ذلك ، يمكن أن تجعل تشغيل البرامج النصية واستكشاف الأخطاء وإصلاحها أمرًا محبطًا بعض الشيء. لحسن الحظ ، يمكننا التغلب على هذا دون إجراء أي تغييرات دائمة كذلك.

    الخطوة 1: انقر نقرًا مزدوجًا للتشغيل.

    لنبدأ بمعالجة المشكلة الأولى - اقترانات الملفات .PS1. لا يمكنك النقر نقرًا مزدوجًا لتشغيل ملفات .PS1 ، ولكن يمكنك تنفيذ ملف .BAT بهذه الطريقة. لذلك ، سنقوم بكتابة ملف دفعي لاستدعاء برنامج PowerShell النصي من سطر الأوامر لنا.

    لذلك لا نضطر إلى إعادة كتابة ملف الدُفعات لكل نص ، أو في كل مرة نقوم بنقل نص برمجي حولها ، ستستخدم متغير self-referencing لإنشاء مسار الملف للبرنامج النصي PowerShell. لجعل هذا العمل ، ستحتاج إلى وضع الملف الدفعي في نفس المجلد مثل البرنامج النصي PowerShell ويكون له نفس اسم الملف. لذلك إذا كان البرنامج النصي لـ PowerShell يسمى "MyScript.ps1" ، فستحتاج إلى تسمية ملف دفعي "MyScript.bat" وتأكد من وجوده في نفس المجلد. ثم ، ضع هذه الخطوط في البرنامج النصي الدفعي:

    ECHO OFF PowerShell.exe -Command "& '٪ ~ dpn0.ps1" "PAUSE

    إذا لم تكن هناك قيود أمان أخرى في مكانها ، فسيكون هذا هو كل ما يتطلبه الأمر لتشغيل البرنامج النصي PowerShell من ملف دفعي. في الواقع ، الخطوط الأولى والأخيرة هي فقط مسألة تفضيل - إنه الخط الثاني الذي يقوم بهذا العمل. وهنا الانهيار:

    @صدى خارج يوقف تشغيل echoing. هذا فقط يبقي الأوامر الأخرى الخاصة بك من الظهور على الشاشة عند تشغيل الملف الدفعي. هذا الخط نفسه مخفي عن طريق استخدام الرمز (@) أمامه.

    PowerShell.exe -Command "& '٪ ~ dpn0.ps1'" يدير فعلا برنامج PowerShell النصي. بالطبع يمكن استدعاء PowerShell.exe من أي نافذة أو ملف دفعي CMD لإطلاق PowerShell إلى وحدة تحكم عارية كالمعتاد. يمكنك أيضًا استخدامه لتشغيل الأوامر مباشرة من ملف دفعي ، من خلال تضمين المعلمة -Command والوسائط المناسبة. الطريقة المستخدمة لاستهداف ملف .PS1 الخاص بنا تكون مع المتغير٪ ~ dpn0 الخاص. تشغيل من ملف دفعي ، يقيّم dpn0٪ إلى حرف محرك الأقراص ومسار المجلد واسم الملف (بدون ملحق) للملف الدفعي. نظرًا لأن ملف الدُفعات والبرنامج النصي PowerShell سيكونان في نفس المجلد ولهما نفس الاسم ، فسيتم ترجمة٪ dpn0.ps1 إلى مسار الملف الكامل للبرنامج النصي PowerShell.

    وقفة مجرد الإيقاف المؤقت لتنفيذ الدُفعة وينتظر إدخال المستخدم. من المفيد عمومًا أن يكون لديك في نهاية ملفات الدفعات الخاصة بك ، بحيث يكون لديك فرصة لمراجعة أي إخراج أمر قبل أن يختفي الإطار. بينما نجري اختبارًا لكل خطوة ، ستصبح فائدة هذا الأمر أكثر وضوحًا.

    لذلك ، تم إعداد ملف الدُفعات الأساسي. لأغراض العرض التوضيحي ، يتم حفظ هذا الملف باسم "D: \ Script Lab \ MyScript.bat" ويوجد "MyScript.ps1" في نفس المجلد. لنرى ما يحدث عندما نضغط مرتين على MyScript.bat.

    من الواضح أن البرنامج النصي PowerShell لم يتم تشغيله ، ولكن هذا أمر متوقع - لقد عالجنا فقط مشكلاتنا الأربعة الأولى ، بعد كل شيء. ومع ذلك ، هناك بعض البتات الهامة الموضحة هنا:

    1. يظهر عنوان النافذة أن البرنامج النصي الدفعي أطلق بنجاح PowerShell.
    2. يوضح السطر الأول من المخرجات أن ملف تعريف PowerShell مخصص قيد الاستخدام. هذه مشكلة محتملة # 4 ، المذكورة أعلاه.
    3. توضح رسالة الخطأ قيود ExecutionPolicy سارية المفعول. هذه مشكلتنا # 2.
    4. يظهر الجزء المسطر من رسالة الخطأ (التي يتم إجراؤها أصلاً بواسطة إخراج خطأ PowerShell) البرنامج النصي الدفعي بشكل صحيح استهداف البرنامج النصي PowerShell المقصود (D: \ Script Lab \ MyScript.ps1). لذلك على الأقل نعرف أن الكثير يعمل بشكل صحيح.

    الملف الشخصي ، في هذه الحالة ، هو برنامج نصي بسيط من سطر واحد يستخدم في هذه المظاهرة لإنشاء مخزون كلما كان الملف الشخصي نشطًا. يمكنك تخصيص ملف تعريف PowerShell الخاص بك للقيام بذلك أيضًا ، إذا كنت ترغب في اختبار هذه البرامج النصية بنفسك. ما عليك سوى إضافة السطر التالي إلى نص البروفايل الخاص بك:

    إخراج "مخصص PowerShell الشخصية سارية المفعول!"

    يتم تعيين ExecutionPolicy على نظام الاختبار هنا إلى RemoteSigned. يسمح ذلك بتنفيذ البرامج النصية التي تم إنشاؤها محليًا (مثل نص البروفايل الشخصي) ، أثناء حظر البرامج النصية من المصادر الخارجية ما لم يتم التوقيع عليها من قبل سلطة موثوق بها. لأغراض العرض التوضيحي ، تم استخدام الأمر التالي للإشارة MyScript.ps1 من مصدر خارجي:

    Add-Content-Path "D: \ Script Lab \ MyScript.ps1 '-Value" [ZoneTransfer]' nZoneId = 3 "-Stream 'Zone.Identifier'

    يقوم بتعيين دفق البيانات البديلة Zone.Identifier على MyScript.ps1 بحيث يعتقد Windows أن الملف جاء من الإنترنت. يمكن عكسها بسهولة باستخدام الأمر التالي:

    مسح المحتوى -Path 'D: \ Script Lab \ MyScript.ps1' -Stream 'Zone.Identifier'

    الخطوة 2: الالتفاف حول ExecutionPolicy.

    الالتفاف حول الإعداد ExecutionPolicy ، من CMD أو البرنامج النصي الدفعي ، في الواقع سهلة للغاية. نقوم فقط بتعديل السطر الثاني من البرنامج النصي لإضافة معلمة أخرى إلى الأمر PowerShell.exe.

    PowerShell.exe -ExecutionPolicy Bypass -Command "& '٪ ~ dpn0.ps1'"

    يمكن استخدام المعلمة -ExecutionPolicy لتعديل ExecutionPolicy المستخدمة عند إنتاج جلسة PowerShell جديدة. لن يستمر هذا بعد هذه الجلسة ، حتى نتمكن من تشغيل PowerShell مثل هذا عندما نحتاج دون إضعاف الموقف الأمني ​​العام للنظام. الآن بعد أن أصلح ذلك ، دعنا نذهب إلى آخر:

    الآن وقد تم تنفيذ النص بشكل صحيح ، يمكننا أن نرى ما يفعله بالفعل. إنه يسمح لنا بمعرفة أننا نقوم بتشغيل البرنامج النصي كمستخدم محدود. في الواقع يتم تشغيل البرنامج النصي بواسطة حساب له أذونات "المسؤول" ، ولكن "التحكم في حساب المستخدم" في طريقه. على الرغم من أن تفاصيل كيفية فحص النص البرمجي لدخول المسؤول خارج نطاق هذه المقالة ، إليك الشفرة المستخدمة في العرض التوضيحي:

    if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()). IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrator")) كتابة - إخراج "قيد التشغيل كمسؤول!" آخر Write-Output 'Running Limited!' Pause

    ستلاحظ أيضًا أن هناك الآن عمليتين "إيقاف مؤقت" في إخراج البرنامج النصي - أحدهما من برنامج PowerShell النصي والآخر من الملف الدفعي. السبب في ذلك سيكون أكثر وضوحًا في الخطوة التالية.

    الخطوة 3: الحصول على وصول المسؤول.

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

    لسوء الحظ ، لا توجد طريقة لتشغيل UAC للارتفاع من داخل ملف دفعي أو جلسة CMD. ومع ذلك ، فإن PowerShell يسمح لنا بالقيام بذلك باستخدام Start-Process. عند استخدامها مع "-Verb RunAs" في وسيطاتها ، ستحاول Start-Process تشغيل تطبيق بأذونات المسؤول. إذا لم تكن جلسة PowerShell مرتفعة بالفعل ، فسيؤدي ذلك إلى تشغيل مطالبة UAC. لاستخدام هذا من ملف الدُفعات لتشغيل البرنامج النصي الخاص بنا ، سينتهي بنا الأمر إلى إنتاج عمليتي PowerShell - واحدة لإيقاف تشغيل Start-Process وأخرى ، يتم تشغيلها بواسطة Start-Process ، لتشغيل البرنامج النصي. يجب تغيير السطر الثاني من ملف الدُفعات إلى هذا:

    PowerShell.exe -Command "& Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File" "٪ ~ dpn0.ps1" "' -Verb RunAs"

    عند تشغيل ملف الدُفعات ، سيكون السطر الأول من المخرجات الذي سنشاهده من نص ملف تعريف PowerShell. بعد ذلك ، سيكون هناك موجه UAC عندما يحاول Start-Process تشغيل MyScript.ps1.

    بعد النقر من خلال مطالبة UAC ، ستظهر نسخة PowerShell جديدة. نظرًا لأن هذا مثال جديد ، بالطبع ، سنرى مرة أخرى إشعار البرنامج النصي للملف الشخصي. ثم ، MyScript.ps1 يعمل ونرى أننا بالفعل في جلسة مرتفعة.

    وهناك سبب لدينا اثنين من التوقف هنا أيضا. إذا لم يكن ذلك في البرنامج النصي PowerShell ، فلن نشاهد إخراج البرنامج النصي مطلقًا - ستظهر نافذة PowerShell وتختفي بمجرد أن يتم تشغيل النص البرمجي. وبدون توقف مؤقت في الملف الدفعي ، لن نكون قادرين على معرفة ما إذا كان هناك أي أخطاء في إطلاق PowerShell في المقام الأول.

    الخطوة 4: التعرف على ملفات تعريف PowerShell المخصصة.

    دعونا نتخلص من هذا الملف الشخصي المخصص سيئة الآن ، فهل نحن؟ هنا ، لا يكاد يكون مصدر إزعاج ، ولكن إذا غيّر الملف الشخصي PowerShell للمستخدم إعدادات أو متغيرات أو وظائف افتراضية بطرق لم تكن تتوقعها مع النص البرمجي ، فيمكن أن تكون مزعجة للغاية. من الأسهل بكثير تشغيل النص البرمجي بدون ملف التعريف بالكامل حتى لا تقلق بشأن هذا الأمر. للقيام بذلك ، نحتاج فقط إلى تغيير السطر الثاني من الملف الدفعي مرة أخرى:

    PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File" "٪ ~ dpn0.ps1" "' -Verb RunAs"

    إن إضافة المعلمة -NoProfile إلى كلتا جهازي PowerShell التي يتم تشغيلها بواسطة البرنامج النصي يعني أنه سيتم تجاوز البرنامج النصي للمستخدم بالكامل في كلا الخطوتين وسيتم تشغيل البرنامج النصي PowerShell في بيئة افتراضية يمكن التنبؤ بها إلى حد كبير. هنا ، يمكنك أن ترى أنه لا يوجد إشعار ملف شخصي مخصص في أي من القذائف التي تم تفريخها.

    إذا لم تكن بحاجة إلى حقوق المسؤول في البرنامج النصي PowerShell ، وقمت بتخطي الخطوة 3 ، فيمكنك القيام بذلك دون مثيل PowerShell الثاني ويجب أن يبدو السطر الثاني من ملف الدُفعة كالتالي:

    PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '٪ ~ dpn0.ps1'"

    سيبدو الناتج كما يلي:

    (وبالطبع ، بالنسبة للنصوص البرمجية لغير المسؤولين ، يمكنك الاستغناء عن إيقاف مؤقت لنهاية البرنامج النصي في البرنامج النصي PowerShell في هذه النقطة أيضًا نظرًا لأنه يتم التقاط كل شيء في إطار وحدة التحكم نفسها وسيتم الاحتفاظ به هناك من خلال الإيقاف المؤقت في نهاية الملف الدفعي على أي حال.)

    ملفات دفعية مكتملة.

    استنادًا إلى ما إذا كنت تحتاج إلى أذونات المسؤول لبرنامج نصي PowerShell (ولا يجب عليك طلب ذلك إذا لم تكن بحاجة إليه) ، يجب أن يبدو الملف الدفعي النهائي كواحد من الاثنين أدناه.

    بدون وصول المشرف:

    ECHO OFF PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '٪ ~ dpn0.ps1'" PAUSE

    مع وصول المشرف:

    echo OFF PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File" "٪ ~ dpn0.ps1" "' -Verb RunAs" PAUSE

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


    المراجع:

    • تشغيل البرامج النصية PowerShell من ملف دفعي - مدونة البرمجة دانيال شرودر
    • التحقق من أذونات المسؤول في PowerShell - Hey، Scripting Guy! مدونة