ما هو Windows PowerShell وماذا يأكل؟ الجزء 3: تمرير المعلمات إلى النصوص والوظائف ، وإنشاء أوامر cmdlets



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

جدول المحتويات:



تمنع المعلمات الموضعية Param ()
سمات المعلمات الإضافية
تمرير المعلمات من خلال
بنية هيكل دالة دالة
السمة [CmdletBinding ()] والوظائف المتقدمة
وحدات البرمجة النصية وإنشاء cmdlets

المعلمات الموضعية


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

Write-Host " :" $args.count
Write-Host ":" $args


صورة

في الوظائف ، يتم استخدام المعلمات الموضعية بالطريقة نفسها:

function Print-Args {
    Write-Host " :" $args.count
    Write-Host " 0:" $args[0]
    Write-Host " 1:" $args[1] 
}

Print-Args “Zero” “One”

يرجى ملاحظة أنه عند استدعاء Print-Args ، فإننا لا نضع فاصلة بين المعلمات: فهي ليست صفيفًا يتم تمريره إلى الوظيفة ، ولكن القيم الفردية المكتوبة على مصفوفة $ args أحادية البعد - نطاقها مقيد بنص الدالة.

صورة

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

كتلة Param ()


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

function test ($arg0, ..., $argN)
{
       
}

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

توصي شركة Microsoft باستخدام كتلة Param () - بناء الجملة هذا أكثر عالمية ويسمح لك بتحديد ليس فقط وسيطات الوظائف ، ولكن أيضًا معلمات البرنامج النصي:

param (
    $arg0, $arg1
)

Write-Host $arg0 $arg1


صورة

في نص الوظيفة ، يبدو كما يلي:

function test {
     param (
           $arg0, $arg1
     )
}

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

سمات المعلمات الإضافية


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

param([int]$arg0)

أو

function test ([int]$arg0) {
}

بالإضافة إلى نوع الإرسال ، يمكنك استخدام السمة [معلمة ()]:

param(
    [parameter(Argument1=value1, Argument2=value2)]
    $ParameterName
)

بمساعدتها ، من السهل جعل المعلمة إلزامية. انتبه إلى الاستخدام المتزامن لعدة سمات - في هذه الحالة يتبعون بعضهم البعض:

param([parameter(Mandatory=$true)][int]$arg0)

أو

function test ([parameter(Mandatory=$true)][int]$arg0) { 
}

أو

function test {
          parameter([parameter(Mandatory=$true)][int]$arg0)
}


صورة

يسمح لك الموضع بتحديد ترتيب المعلمة (افتراضيًا ، يتوافق مع ترتيب الإعلان):

param(
                    [parameter(Mandatory=$true, Position=0)]
                    [int]
                    $arg0,

                    [parameter(Position=1)]
                    [string]
                    $arg1,

                    [parameter(Position=2)]
                    [array]
                    $arg2
)

تحتوي السمة [Parameter ()] على وسيطات أخرى ، تتوفر قائمة كاملة بها على موقع Microsoft على الويب . يتم وصف السمات الأخرى هناك ، والتي يمكنك من خلالها التحقق من القيم التي تم تمريرها ، والتحقق منها باستخدام التعبيرات العادية ، وما إلى ذلك. إليك بعض

الأمثلة : [Alias ​​()] يعين اسمًا مستعارًا للمعلمة:

param(
    [parameter(Mandatory=$true)]
    [alias("ARG","ArgumentName")]
    [string[]]
    $arg0
)

عامل الإرسال [string []] يعني أن قيمة المعلمة هي مصفوفة سلسلة.

[AllowNull ()] يسمح $ null كمعلمة مطلوبة:

param(
    [parameter(Mandatory=$true)]
    [AllowNull()]
    [string]
    $arg0
)

[AllowEmptyString ()] يسمح بسلسلة فارغة كمعلمة مطلوبة:

param(
    [parameter(Mandatory=$true)]
    [AllowEmptyString()]
    [string]
    $arg0
)

[AllowEmptyCollection ()] يسمح بمصفوفة فارغة كمعلمة مطلوبة:

param(
    [parameter(Mandatory=$true)]
    [AllowEmptyCollection()]
    [string[]]
    $arg0
)

[ValidatePattern ()] التحقق باستخدام تعبير عادي:

param(
    [parameter(Mandatory=$true)]
    [ValidatePattern("[0-9][0-9][0-9][0-9]")]
    [string[]]
    $arg0
)

يتحقق [ValidateLength ()] من طول معلمة السلسلة:

param(
    [parameter(Mandatory=$true)]
    [ValidateLength(1,10)]
    [string]
    $arg0
)

تمرير المعلمات عبر خط الأنابيب


في المقالة الأولى من السلسلة ، تحدثنا عن إمكانية نقل البيانات إلى أوامر cmdlets عبر خط أنابيب. في PowerShell ، تقوم أوامر cmdlets والوظائف بإرجاع كائنات أو صفائف من الكائنات (نتائج البيانات) ، وكذلك استقبالها عند الإدخال. لرؤية هذا ، نقوم بإعداد أحد أوامر cmdlets باستخدام Get-Help:

Get-Help Stop-Process -Parameter Name


صورة

من خلال خط الأنابيب ، يمكنك قبول قيم المعلمات التي يتم تعيين السمات المقابلة لها (ByValue و / أو ByPropertyName). في الحالة الأولى ، ستتم مطابقة المعلمة مع كائن تم تلقيه عبر خط الأنابيب ، شريطة أن يتوافق نوعه مع الكائن المتوقع. في قيمة المعلمة الثانية ستكون خاصية الكائن الوارد الذي يتوافق اسمه مع اسم أو اسم مستعار لهذه المعلمة. لتعيين السمات ، استخدم [معلمة ()] مع الوسيطات المنطقية ValueFromPipeline و ValueFromPipelineByPropertyName ، التي قيمتها الافتراضية هي $ false:

param(
    [parameter(Mandatory=$true,
    ValueFromPipeline=$true)]
    [string[]]
    $Name
)

أو

param(
    [parameter(Mandatory=$true,
    ValueFromPipelineByPropertyName=$true)]
    [string[]]
    $Name
)

عادةً ما يتم استخدام ValueFromPipelineByPropertyName إذا لزم الأمر لتمرير عدة معلمات بحيث لا يكون هناك أي لبس ، ويمكن استخدام الوسيطة في نفس الوقت مع ValueFromPipeline:

param(
    [parameter(Mandatory=$true,
    ValueFromPipeline=$true,
    ValueFromPipelineByPropertyName=$true)]
    [string[]]
    $Name
)

Write-Host $Name


صورة

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

هيكل جسم الوظيفة


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

function test
{
   param()
   begin {}
   process {}
   end {}
}

كتلة Begin هي الأولى التي يتم تنفيذها مرة واحدة ، وإذا تم تمرير المعلمات إلى الوظيفة من خلال خط الأنابيب ، فسيتم تشغيل الشفرة قبل وصول الكائن الأول للمعالجة. لن يحتوي متغير $ _ و $ PSItem في كتلة Begin في هذه الحالة على قيم. إذا تم استدعاء الوظيفة باستخدام معلمات محددة بشكل صريح ، فستكون متاحة في كتلة Begin ، حيث لا توجد حاجة لانتظار استلام الكائنات من خط الأنابيب. بعد ذلك ، يتم تنفيذ كتلة العملية: إذا تم تمرير المعلمات عبر خط الأنابيب ، فسيتم تشغيلها بدوره لكل كائن. في حالة المعلمات المحددة بشكل صريح ، تبدأ كتلة العملية مرة واحدة فقط. تنتهي الوظيفة بتنفيذ كتلة النهاية مرة واحدة. من الواضح أن استخدام هذه الإنشاءات له ما يبرره فقط إذا كانت الوظيفة يمكن أن تتلقى أشياء من خط الأنابيب:

function test
{

    param(
        [Parameter(ValueFromPipeline)]
        [string[]]
        $Param1,

        [string]$Param2
    )

    begin
    {
        Write-Host " Begin"
        Write-Host "       ( pipeline):" $Param1
        Write-Host "       ( ):" $Param2
    }

    process {
        Write-Host " Process"
        Write-Host "       ( pipeline):" $Param1
        Write-Host "       ( ):" $Param2
    }

    end
    {
        Write-Host " End"
        Write-Host "       ( pipeline):" $Param1
        Write-Host "       ( ):" $Param2
    }
}

'one'، 'two'، 'three' | اختبار -Param2 "أربعة"

صورة

[CmdletBinding ()] السمة والوظائف المتقدمة


لإنشاء دالات "متقدمة" (ونصوص برمجية) ، يمكنك استخدام السمة [ CmdletBinding () ]. على وجه الخصوص ، يسمح لك بتعريف الوظائف المتقدمة مع إمكانيات cmdlets الثنائية المترجمة في Visual Studio ، وهي فئات من فئات .NET Core. نظرًا لأن هذه السمة تستخدم بشكل أساسي في الوظائف ، فسوف نتوقف عليها:

function <Name>
{
    [CmdletBinding(ConfirmImpact=<String>,
    DefaultParameterSetName=<String>,
    HelpURI=<URI>,
    SupportsPaging=<Boolean>,
    SupportsShouldProcess=<Boolean>,
    PositionalBinding=<Boolean>)]

    Param ()

    Begin{}
    Process{}
    End{}
}

في الواقع ، يقوم [CmdletBinding ()] بتهيئة مثيل جديد لفئة CmdletBindingAttribute عن طريق استدعاء المُنشئ ، والذي يمكن تمرير الوسيطات الاختيارية إليه. وصفهم التفصيلي موجود على موقع Microsoft على ويب . تسمح لك سمة CmdletBinding بالتحكم في الميزات الإضافية للوظيفة المتقدمة: إضافة دعم لـ -Confirm و -WhatIf (عبر SupportsShouldProcess) و -Force و -Verbose و -Dugug ، بالإضافة إلى تعطيل ربط المعلمات الموضعية وما إلى ذلك. علاوة على ذلك سنقوم بتحليل استخدام المعلمات الخاصة. يتم استخدام

المعلمة -Force لقمع الطلبات لعمليات مختلفة ؛

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

Remove-Item C: \ Windows \ notepad.exe -WhatIf

صورة

-Confirm يتطلب تأكيدًا ويستخدم أيضًا إذا كان بإمكان الوظيفة تنفيذ إجراءات مدمرة.

function Delete-File {
[CmdletBinding(
    ConfirmImpact = 'High',
    SupportsShouldProcess = $true
)]
    param(
        [string]$File,
        [switch]$Force
    )
    if ($Force -or $PSCmdlet.ShouldProcess($File,"Delete file")) {
        Remove-Item $File
    }
}


صورة

لمعالجة -WhatIf و / أو -Confirm ، يتم استدعاء أسلوب shouldProcess (SupportsShouldProcess = $ true) ، والذي يطالب بتنفيذ الأمر أو يحاكيه. لتنفيذ معالجة -Force ، نضعه أولاً في حالة IF. أولاً ، يتم التحقق من التعبير على يسار عامل التشغيل -أو إذا كان صحيحًا ، يتوقف الاختبار - لن يتم استدعاء طريقة shouldProcess. أيضًا ، في السمة [CmdletBinding ()] ، حددنا وسيطة ConfirmImpact ، التي تحدد مستوى تأثير الشفرة على النظام وتتضمن معالج المعلمة -Confirm. يمكن أن تأخذ هذه الوسيطة القيم التالية:

لا شيء أو لم يتم تحديدها - لن يتم عرض رسائل التأكيد ، حتى إذا تم تمرير المعلمة -Confirm.

منخفضة - تؤثر الوظيفة بشكل طفيف على النظام ولا تخلق مخاطر كبيرة لفقدان البيانات.

المتوسطة - التعرض المتوسط مع مخاطر قليلة من فقدان البيانات نتيجة للإجراءات الهدامة.

عالية - يخلق الرمز خطرًا كبيرًا لفقدان البيانات نتيجة الإجراءات المدمرة.

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

خيارات -Verbose و -Dugugاللازمة لعرض معلومات التصحيح. يعتبر استخدامها أسلوب برمجة جيد (ننسى الكتابة المضيف ، وهذا ليس ضروريًا في الوظائف المتقدمة). تعرض المعلمة الأولى معلومات حول التقدم ، ومعلومات التصحيح الثانية المفصلة. كما أنه يجعل من الممكن التبديل إلى تنفيذ التعليمات البرمجية خطوة بخطوة. يتم تعريف سلوك -Verbose و -Dugug على النحو التالي:

function Get-Something {
[CmdletBinding()]
    param()
    if ($PSBoundParameters.Verbose) {$VerbosePreference = "Continue"}
    if ($PSBoundParameters.Debug) {$DebugPreference = "Continue"}
    Write-Verbose "Type some verbose information"
    Write-Debug "Type some debug information"
}

للعمل مع المعلمات الخاصة ، استخدمنا المتغير $ PSBoundParameters. افتراضيًا ، تكون قيم $ VerbosePreference و $ DebugPreference تساوي "SilentlyContinue" ، وبالتالي ، حتى إذا تم تحديد المعلمات المقابلة ، فلن يتم عرض معلومات التصحيح - يجب نقلها إلى حالة "متابعة".

وحدات البرنامج النصي وإنشاء أمر Cmdlet


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

Get-ChildItem Env: \ PSModulePath | تنسيق الجدول-الحجم التلقائي

تبدو المجموعة القياسية شيئًا مثل هذا:

C: \ Users \٪ UserName٪ \ Documents \ WindowsPowerShell \ Modules
C: \ Program Files \ WindowsPowerShell \ Modules
C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Modules

بعد إنشاء ملف ModuleName.psm1 باستخدام وظيفة Delete-File الممتدة من القسم السابق ، تحتاج إلى حفظه ، على سبيل المثال ، في] C: \ Users \٪ UserName٪ \ Documents \ WindowsPowerShell \ Modules \ ModuleName. يرجى ملاحظة أنه يجب تخزين وحدة البرنامج النصي في دليل فرعي منفصل ، يتزامن اسمها مع الاسم الأساسي (بدون ملحق) لملف .psm1. بعد تشغيل الأمر Import-Module ModuleName ، ستصبح وظيفة حذف الملف متاحة للمستخدم ، ولأنها متقدمة ، فهي من نفس الأمر cmdlet من الناحية العملية.

صورة

في هذه المقالة ، درسنا بتفصيل كافٍ تمرير المعلمات إلى الدوال والنصوص. سيركز الجزء التالي من السلسلة على البرمجة الشيئية.

الجزء 1: أساسيات Windows PowerShell
2: Windows PowerShell
4: ,



All Articles