أتمتة المهام مع PowerShell PSake: جولة تعليمية

لقد تعلمت كيفية أتمتة المهام باستخدام سكريبت PowerShell. هذا رائع! ولكن الآن لديك مجموعة من السكربتات والوحدات المنظمة بشكل مبعثر مع تنفيذ سكربتات يدويًا ومهام مجدولة وغيرها. حان الوقت لجلب بعض النظام للفوضى وتنفيذ محرك التنسيق التلقائي المعروف بـ PowerShell. PSake

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

في هذا البرنامج التعليمي ، ستتعلم كيف يعمل PSake بالإضافة إلى بعض الأمثلة الرائعة التي يمكنك تطبيقها اليوم!

المتطلبات الأساسية.

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

  • Windows PowerShell 3+ . يستخدم البرنامج التعليمي Windows PowerShell v5.1
  • ملف PSake zip من Github. يستخدم هذا البرنامج التعليمي الإصدار v4.9.0.

إعداد وحدة PSake.

بفرض أن لديك مشروع PSake من GitHub على جهازك المحلي ، ستحتاج في البداية إلى المرور عبر عدد قليل من الخطوات لإعداده.

  1. استخراج ملف PSake zip الذي تم تنزيله من GitHub.
  2. قم بنقل مجلد src داخل محتويات ملف ZIP المستخرج إلى مسار تحت $env:PSModulePath لضمان أن PowerShell يعرف عن الوحدة النمطية الجديدة.
  3. قم بإعادة تسمية مجلد src إلى PSake.
  4. قم الآن بتشغيل Get-Module PSake -ListAvailable للتأكد من ظهوره. إذا لم تتلق أي خطأ، فأنت جاهز للمتابعة.

ذات صلة: فهم وبناء وحدات PowerShell

إنشاء سيناريو PowerShell PSake أساسي

لفهم PSake ، تحتاج إلى بناء شيء. دعنا نبني سيناريو PSake بسيط لنرى ما يمكنه القيام به.

  1. قم بإنشاء سيناريو بأسم psakefile.ps1 يحتوي على مهمة واحدة. على الأقل ، يجب أن تحتوي المهمة على اسم ومجموعة إجراءات. اسم psakefile.ps1 ليس إلزاميًا ، ولكنه هو الاسم الافتراضي المتوقع من المحرك.

A PSake task in its basic form is very similar to a PowerShell function:
a container for one or more commands that, when performed together, achieve a certain goal. These commands go into a script block that is passed to the Action parameter. A task has many advantages over a function. You will learn about these advantages as you read along.

فيما يلي مثال على psakefile.ps1 يحتوي على مهمة بسيطة إلى حد ما:

task HelloWorld -Action {
    Write-Host '*** Hello World ***' -ForegroundColor Yellow
}

2. الآن بعد بناء ملف PSake ، يمكنك استدعائه من وحدة التحكم PowerShell باستخدام الأمر Invoke-PSake وتمرير اسم المهمة كقيمة لمعلمة TaskList .

Invoke-PSake هو محرك التنفيذ لـ PSake. هذا الأمر يقوم بتشغيل المهام المحددة في ملف psakefile.ps1. يمكنك تمرير اسم المهمة أو قائمة المهام المفصولة بفواصل إلى معلمة TaskList. إذا كنت تنفذ مهامًا متعددة، ستنفذ كل مهمة في الترتيب الذي تم تمريره إليها في TaskList بغض النظر عن موقعها في ملف psakefile.ps1.

أدناه كيفية تشغيل المهمة HelloWorld:

Invoke-PSake -BuildFile C:\Work\psakefile.ps1 -TaskList 'HelloWorld'

طالما أنك تحتفظ بالاسم psakefile.ps1، وبشرط أن تعيد الوحدة إلى المجلد الذي يتواجد فيه، يمكنك تجاهل معلمة BuildFile وقيمتها.

  1. عند تشغيل Invoke-PSake سيظهر نتائج PSake في وحدة التحكم. عند تنفيذ المهام في psakefile.ps1، سترى نتائج مشابهة لما تراه أدناه.
Psake script output

تتكون النتائج من العناصر التالية:

  1. تفاصيل حول إصدار PSake.
  2. اسم كل مهمة قبل تشغيلها (يعتبر PSake كل مهمة كمهمة بناء). في المثال: تنفيذ HelloWorld باللون الأزرق الفاتح.
  3. أي إخراج تنتجه المهمة. في المثال: Hello World باللون الأصفر.
  4. رسالة نجاح/فشل. في المثال: نجحت عملية psake… باللون الأخضر.
  5. ملخص الوقت (يسمى تقرير وقت البناء) مع مدة كل مهمة، بالإضافة إلى المدة الإجمالية للنص البرمجي كامل.

تثبيت SQL باستخدام PSake

في القسم السابق، لم تفعل الكثير سوى استدعاء نص برمجي وهمي لـ PSake. الآن، قم بالاستفادة من هذه المعرفة وقم بإنشاء نص برمجي لـ PSake يقوم بتثبيت SQL!

في هذا المثال ، ستقوم بإنشاء سكريبت PSake يقوم بما يلي:

  1. يقوم بالتحقق من المساحة الحرة على القرص في الجهاز.
  2. يقوم بتنزيل ملف ZIP من مستودع محلي لقاعدة بيانات SQL.
  3. يقوم بفك ضغط ملف ZIP.
  4. يقوم بتشغيل عملية التثبيت على القرص C أو D (أيهما موجود).

دعنا نرى كيف يمكننا استخدام PSake للقيام بذلك.

تصميم كتل البناء

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

  1. ValidateDiskSpace
  2. DownloadSql
  3. ExtractSql
  4. InstallSqlDriveC
  5. InstallSqlDriveD

في هذه المرحلة ، لا تقوم ببناء الشيفرة الفعلية للقيام بأي شيء ؛ بل تقوم بإنشاء هياكل المهام وإنشاء ملف PSake. ستلاحظ مراجعات Write-Host في المهام أدناه ؛ ستقوم بإضافة المزيد إلى المهام لاحقًا.

يجب دائمًا استخدام معلمة Description لكل مهمة. توفر معلمة Description مزيدًا من المعلومات حول كل مهمة عند تنفيذ المهام وأثناء مراجعة الشيفرة.

task ValidateDiskSpace -Description 'Validate Disk Free Space' -Action {
	
	Write-Host "`n   *** Checking disk free space ***`n" -ForegroundColor Yellow
	
}

task DownloadSql -Description 'Download SQL Setup' -Action {
	
	Write-Host "`n   *** Downloading SQL Setup from LAN ***`n" -ForegroundColor Yellow
	
}

task ExtractSql -Description 'Extract SQL Setup' -Action {
	
	Write-Host "`n   *** Extracting SQL Setup files ***`n" -ForegroundColor Yellow
	
}

task InstallSqlDriveC -Description 'Install SQL on C:' -Action {
	
	Write-Host "`n   *** Installing SQL Server on C drive ... please wait... ***`n" -ForegroundColor Yellow

}

task InstallSqlDriveD -Description 'Install SQL on D:' -Action {
	
	Write-Host "`n   *** Installing SQL Server on D drive ... please wait... ***`n" -ForegroundColor Yellow
	
}

تعريف ترتيب تنفيذ المهام

لديك الآن ملف PSake يحتوي على مجموعة من المهام. في هذه المرحلة ، يمكنك تشغيل جميع المهام مرة واحدة أو تختار تنفيذ بعضها فقط باستخدام الأمر Invoke-PSake.

يمكنك استدعاء بعض (أو جميع المهام) باستخدام Invoke-PSake والمعلمة TaskList كما فعلت سابقًا في المثال البسيط. إذا كان لديك أكثر من مهمة لاستدعائها ، قم بإنشاء مصفوفة وتعريف اسم كل مهمة كعنصر كما هو موضح أدناه.

سوف يقوم Invoke-PSake بتشغيل كل مهمة وفقًا للترتيب المحدد في المصفوفة.

$taskList = @()

$taskList += 'ValidateDiskSpace'
$taskList += 'DownloadSql'
$taskList += 'ExtractSql'
$taskList += 'InstallSqlDriveC'
$taskList += 'InstallSqlDriveD'

Invoke-PSake -TaskList $taskList

عند تشغيل الكود أعلاه ، يجب أن تحصل على نتيجة مشابهة للتالية:

PSake script output

إضافة شرط مسبق

ربما تحتاج إلى تنفيذ بعض الإجراءات فقط إذا تم تلبية شرط معين. في سكريبت تثبيت SQL المستخدم في هذا البرنامج التعليمي ، على سبيل المثال ، قد تحتاج إلى اختبار ما إذا كان الحجم الذي تخزن فيه البرنامج المثبت متاحًا قبل تنفيذ المهمة لاستدعاء ذلك المثبت.

يمكنك استخدام معلمة PreCondition لتنفيذ قطعة من الكود تعيد قيمة True أو False تحدد ما إذا كانت تلك المهمة ستعمل أم لا.

لاحظ في المثال أدناه المتغيرات $installSqlOn_C_Drive و $installSqlOn_D_Drive. عندما يقوم Invoke-PSake بدعوة هذا البرنامج النصي ، ستحتوي هذه المتغيرات على قيمة True أو False اعتمادًا على ما إذا كان الحجم C أو D موجودًا.

على كل سطر task ، يمكنك رؤية أن لكل مهمة معلمة كتلة البرنامج النصي PreCondition التي تحتوي على قيمة تلك المتغيرات. في وقت التشغيل ، سيتم تشغيل إما مهمة InstallSqlDriveC أو مهمة InstallSqlDriveD ، اعتمادًا على هذه المتغيرات.

$installSqlOn_C_Drive = (Test-Path -Path 'C:') -and (-not (Test-Path -Path 'D:'))
$installSqlOn_D_Drive = (-not (Test-Path -Path 'C:')) -and (Test-Path -Path 'D:')

task InstallSqlDriveC -Description 'Install SQL on C:' -PreCondition { $installSqlOn_C_Drive } -Action {
	
	Write-Host "`n   *** Installing SQL Server on C drive ... please wait... ***`n" -ForegroundColor Yellow
	
}

task InstallSqlDriveD -Description 'Install SQL on D:' -PreCondition { $installSqlOn_D_Drive } -Action {
	
	Write-Host "`n   *** Installing SQL Server on D drive ... please wait... ***`n" -ForegroundColor Yellow
	
}

معلمات المهمة

بالإضافة إلى Action و Description ، تدعم المهمة أيضًا هذه المعلمات:

  • PreCondition – كتلة سيناريو تعيد قيمة بولية. في حالة القيمة البولية False ، يتم تخطي المهمة المحددة. (مثال على الاستخدام موضح أعلاه).
  • PostCondition – خطوة التحقق. كتلة سيناريو تعيد قيمة بولية. القيمة False تعني فشل التحقق وتوقف السيناريو بأكمله.
  • PreAction – كتلة سيناريو لتشغيلها قبل المهمة.
  • PostAction – كتلة سيناريو لتشغيلها فور اكتمال المهمة بنجاح.
  • ContinueOnError – مفتاح تبديل. إذا تم استخدامه ، فلن يؤدي أي أخطاء قد تحدث أثناء تشغيل المهمة إلى كسر السيناريو بأكمله.
  • Depends – اسم مهمة (أو قائمة أسماء المهام) التي يجب تشغيلها قبل تنفيذ المهمة الحالية. ستستخدم PSake هذه المعلومات لتنفيذ تبعيات المهمة بالترتيب الصحيح. على سبيل المثال ، إذا كانت المهمة A معتمدة على المهمة B ، فسيقوم محرك PSake بتشغيل B قبل A.

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

دعنا نرى مثال استخدام لبعض هذه المعلمات للمهمة التالية:

إضافة الإجراء المسبق والشرط اللاحق

باستخدام مهمة InstallSqlDriveD من المثال أعلاه كنقطة انطلاق، ربما لديك طلب إضافي للتثبيت.

ربما تحتاج إلى تسجيل أوقات بدء وانتهاء التثبيت. تحتاج إلى تسجيل هذه الأوقات في متغيرات بيئة تسمى SqlSetupStartDate و SqlSetupEndDate. ثانيًا، بعد اكتمال التثبيت، تحتاج إلى التحقق من عدم وجود مجلد D:\TempSqlFiles.

لحسن الحظ، تلبي معاملات مهمة PSake PreAction، PostAction و PostCondition (على التوالي) هذه المتطلبات الجديدة بالضبط. فيما يلي مثال على كيفية تحقيق ذلك:

task InstallSqlDriveD -Description 'Install SQL on D:' -PreAction {

     Write-Host '*** Writing SQL install start time to env. var. SqlSetupStartDate ***' -ForegroundColor Yellow
     $date = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
[Environment]::SetEnvironmentVariable('SqlSetupStartDate',$date,'Machine')

 } -PreCondition { 

     $installSqlOn_D_Drive

 } -Action {  
  
     Write-Host '*** Installing SQL Server on D drive... please wait... ***' -ForegroundColor Yellow 

} -PostAction {     

    Write-Host '*** Writing SQL install end time to env. var. SqlSetupEndDate ***' -ForegroundColor Yellow     
    $date = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
[Environment]::SetEnvironmentVariable('SqlSetupEndDate',$date,'Machine') 

} -PostCondition { 
    
Write-Host '*** Verifying temp files deleted ***' -ForegroundColor Yellow
     # في حالة وجود المجلد، سيتم إرجاع قيمة False وسيتوقف البرنامج بأكمله
     (-not (Test-Path -Path 'D:\TempSqlFiles'))

 }

تشغيل نصوص PSake في اختبارات Pester

أينما يمكنك استدعاء نص PowerShell، يمكنك استدعاء ملف PSake. إذا كنت تقوم ببناء اختبارات البنية التحتية باستخدام Pester، فيمكنك استدعاء PSake داخل الاختبارات.

ذات الصلة: كتابة اختبارات Pester لـ PowerShell

على سبيل المثال، ربما لديك اختبار Pester للتحقق من وجود ملف ZIP لإعداد SQL في مجلد بعد تشغيل مهمة DownloadSql. في هذه الحالة، تقوم ببناء اختبار Pester بسيط وتستدعي مهمة DownloadSql داخل الاختبار وتتحقق من وجود ملف ZIP فور تشغيلها.

Describe 'SQL install with PSake' {

    It 'Downloads Sql files' {

        $setup = 'C:\Downloads\SqlSetup.zip'

        if(Test-Path -Path $setup)
        {
            Remove-Item -Path $setup
        }

        # المهمة الوحيدة المختبرة هنا هي DownloadSql
        Invoke-PSake -BuildFile C:\Work\psakefile.ps1 -TaskList DownloadSql
        
        $setup | Should -Exist
    }
}

تمرير المعلمات إلى المهام

عندما تبدأ في استخدام PSake ، قد ترغب في تمرير بعض المعلمات إلى بعض المهام. عادةً ما تمرر معلمات مسماة مختلفة إلى الوظيفة/النص البرمجي في PowerShell ، ولكن PSake مختلفة.

لتمرير المعلمات إلى ملفات PSake ، يمكنك استخدام كتلة الخصائص التي تعرف أزواج المفاتيح/القيم التي يتاح لـ PSake استخدامها داخل كل مهمة في الملف.

تأكد من تعريف كتلة الخصائص في أعلى ملف PSake. يتم قراءة جميع عمليات PSake من أعلى إلى أسفل.

على سبيل المثال ، لتمرير المتغيرات الديناميكية SqlYear و SqlVersion إلى كل مهمة في ملف PSake ، يمكنك تعريفها كما هو موضح أدناه.

Properties {
    $SqlYear = '2017'
    $SqlVersion = '14.0'
}

task -Name DownloadSql -Action {
    
    Write-Host "SQL version to install: SQL $SqlYear (version $SqlVersion)"

}

عندما تقوم بتنفيذ ملف PSake باستخدام Invoke-PSake ، سترى الناتج التالي. لاحظ أن المتغيرات $SqlYear و $SqlVersion قد تم توسيعها بالقيم المعرفة في كتلة الخصائص.

psake version 4.9.1
Copyright (c) 2010-2018 James Kovacs & Contributors

Executing DownloadSql
SQL version to install: SQL 2017 (version 14.0)

psake succeeded executing C:\Work\PSakefile.ps1

--------------------------------------------------
Build Time Report
--------------------------------------------------

Name        Duration
----        --------
DownloadSql 00:00:00
------      --------
Total:      00:00:00

استخدام معلمة الخصائص

إذا كنت تفضل تمرير المعلمات إلى مهمة عبر معلمة تقليدية ، يمكن أن يساعدك PSake. لا تزال بحاجة إلى الاحتفاظ بكتلة الخصائص في أعلى psakefile.ps1 كما هو موضح أعلاه ، ولكن PSake يتيح لك تجاوز القيم.

للقيام بذلك ، قم بتعريف جدول مع كل من زوجي المفتاح / القيمة التي ترغب في تجاوزها. ثم ، قم بتمرير الجدول إلى المعلمة الخصائص. ستستخدم محرك PSake القيم في الجدول الممر على تلك المحددة في كتلة الخصائص داخل نصي psakefile.ps1.

لاحظ الاختلافات في البناء بين كتلة الخصائص ومعلمة الخصائص. في كتلة الخصائص ، كل سطر هو متغير وبالتالي مسبوق برمز الدولار ، بينما معلمة الخصائص هي جدول مع كل عنصر هو مفتاح ، ومكتوب بدون رمز الدولار السابق. اختلاف آخر هو أن الجدول الممر يسبقه حرف @.

فيما يلي مثال على استخدام معلمة الخصائص.

$myNewProperties = @{
    SqlYear = '2019'
    SqlVersion = '15.0'
}

Invoke-PSake -TaskList DownloadSql -Properties $myNewProperties

تجزئة المهام في PSake: المهام كملفات

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

ذات الصلة: كيفية البقاء على قيد الحياة أثناء إعادة تنظيم نص PowerShell من الجحيم

في مثال هذا البرنامج التعليمي ، كنت تعمل مع خمسة مهام:

  • تحقق من مساحة القرص
  • تنزيل SQL
  • استخراج SQL
  • تثبيت محرك SQL في محرك C
  • تثبيت محرك SQL في محرك D

يتم تعريف كل من هذه المهام داخل نص سكريبت pssakefile.ps1 واحد. إذا كنت تتوقع إضافة المزيد من المهام مع مرور الوقت ، فيجب عليك تقسيم تلك المهام إلى ملفات منفصلة ، حيث يحتوي كل ملف على مهمة واحدة على سبيل المثال ValidateDiskSpace.ps1، DownloadSql.ps1، InstallSqlDriveD.ps1، InstallSqlDriveD.ps1 ، الخ.

على سبيل المثال ، سوف يحتوي ملف InstallSqlDriveD.ps1 على هذا الكود فقط:

task InstallSqlDriveD -Description 'Install SQL on D:' -PreCondition { $installSqlOn_D_Drive } -Action {
	
	Write-Host "`n   *** Installing SQL Server on D drive ... please wait... ***`n" -ForegroundColor Yellow
	
}

بمجرد نقل المهام إلى خارج الملف ، استورد الملفات إلى psakefile.ps1 باستخدام وظيفة Include. بمجرد القيام بذلك ، يتم تقليل محتوى psakefile.ps1 إلى هذا الكود:

$installSqlOn_C_Drive = $true
$installSqlOn_D_Drive = $false

Include "$PSScriptRoot\ValidateDiskSpace.ps1"
Include "$PSScriptRoot\DownloadSql.ps1"
Include "$PSScriptRoot\ExtractSql.ps1"
Include "$PSScriptRoot\InstallSqlOnC.ps1"
Include "$PSScriptRoot\InstallSqlOnD.ps1"

عندما يشغل النص البرمجي Invoke-PSake النص البرمجي psakefile.ps1 ، لا يعرف أو يهتم Invoke-PSake بما إذا كانت المهام داخل ملف psake أم تم استيرادها بواسطة طريقة Include.

الخطوات التالية

PSake هو مخطط نص قوي يمكن استخدامه لأغراض عديدة: بناء البرامج النصية ، CI / CD ، نشر الحزم ، إنشاء المثبتات والمزيد. الحد الوحيد هو خيالك. الاعتياد على بناء النصوص الكبيرة باستخدام PSake يجعلك تفكر في المهام (كتل البناء البرمجية). يستفيد مفهوم المهام من بناء البرامج القوة النصية ، وباستخدام المهام ستثري معرفتك الحالية بسطر الأوامر في PowerShell.

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

أين ترى أن PSake يناسب مشاريع العمل الخاصة بك؟

Source:
https://adamtheautomator.com/powershell-psake/