معلمات باور شيل: فتح قوة البرمجة النصية

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

في هذا المقال، ستتعلم كل جانب من جوانب إنشاء واستخدام وسائط أو وسيطات باورشيل!

هذا مثال من كتابي “باورشيل لمسؤولي النظام”. إذا كنت ترغب في تعلم باورشيل أو استعراض بعض حيل المهنة، تحقق منه!

لماذا تحتاج إلى وسيط باورشيل؟

عندما تبدأ في إنشاء وظائف، ستكون لديك خيار لتضمين وسائط أو عدم تضمينها وكيفية عمل تلك الوسائط.

لنفترض أن لديك وظيفة تقوم بتثبيت Microsoft Office. ربما يتصل البرنامج التثبيت لـ Office صامتًا داخل الوظيفة. ما تقوم به الوظيفة لا يهم لأغراضنا. تبدو الوظيفة الأساسية مثل هذا مع اسم الوظيفة وكتلة النص.

function Install-Office {
    ## قم بتشغيل برنامج التثبيت الصامت هنا
}

في هذا المثال، قمت بتشغيل Install-Office بدون وسائط وقام بمهمته.

لم يكن له أهمية ما إذا كانت لدى وظيفة Install-Office وسائط أم لا. على ما يبدو، لم يكن لديها أي وسائط إلزامية. وإلا، لما سمح باورشيل لنا بتشغيلها بدون استخدام وسيط.

عند استخدام وسيط باورشيل

المكتب لديه الكثير من الإصدارات المختلفة. ربما تحتاج إلى تثبيت Office 2013 و 2016. حالياً، ليس لديك وسيلة لتحديد هذا. يمكنك تغيير كود الوظيفة في كل مرة تريد تغيير السلوك.

على سبيل المثال، يمكنك إنشاء وظيفتين منفصلتين لتثبيت إصدارات مختلفة.

function Install-Office2013 {
    Write-Host 'I installed Office 2013. Yippee!'
}

function Install-Office2016 {
    Write-Host 'I installed Office 2016. Yippee!'
}

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

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

نعم! المعلمات أو ما يسميه البعض بالمؤثرات.

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

قبل أن تفكر بسرعة في معلم PowerShell لاستخدامه، من الضروري أولاً أن تسأل نفسك سؤالًا؛ “ما هي أصغر تغييرات تتوقع أن تكون مطلوبة في هذه الوظيفة؟”.

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

لذا تعرف أنك بحاجة إلى معلمة “الإصدار”. ماذا الآن؟ يمكنك الآن إضافة واحدة، ولكن مثل أي لغة برمجة رائعة، هناك طرق متعددة لذلك.

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

هناك شيء يسمى معلمات الوضع. تتيح لك هذه المعلمات تمرير قيم إلى المعلمات دون تحديد اسم المعلمة. تعمل المعلمات الوضعية ولكن لا يعتبر استخدامها “أفضل تمرين عمل”؛ لماذا؟ لأنها أصعب قراءتها خاصة عندما يكون لديك العديد من المعلمات المحددة في وظيفة.

إنشاء معلمة PowerShell بسيطة

يتطلب إنشاء معلمة في وظيفة مكونين رئيسيين؛ كتلة param والمعلمة نفسها. تعرف كتلة param بواسطة الكلمة الرئيسية param تليها مجموعة من الأقواس.

An example of a param block
function Install-Office { [CmdletBinding()] param() Write-Host 'I installed Office 2016. Yippee!' }

في هذه النقطة، لم تتغير وظيفة الوظيفة الفعلية على الإطلاق. لقد قمنا فقط بتجميع بعض الأنابيب، مما يعدنا جاهزين لإنشاء أول معلمة.

بمجرد أن نضع كتلة param في مكانها، ستقوم الآن بإنشاء المعلمة. الطريقة التي أقترح عليك من خلق معلمة تتضمن كتلة Parameter، تليها نوع المعلمة، يليها اسم المتغير المعلم أدناه.

An example of a param block
function Install-Office { [CmdletBinding()] param( [Parameter()] [string]$Version ) Write-Host 'I installed Office 2016. Yippee!' }

لقد قمنا الآن بإنشاء معلمة وظيفية في PowerShell، ولكن ماذا حدث بالضبط هنا؟

كتلة Parameter هي قطعة اختيارية ولكن مستحسنة في كل معلم. مثل كتلة param، إنها “أنابيب الوظيفة”، التي تعد المعلمة لإضافة وظائف إضافية. السطر الثاني هو حيث تعرف نوع المعلمة.

في هذه الحالة، قررنا تحويل معلمة Version إلى سلسلة نصية. تعريف نوع صريح يعني أن أي قيمة تُمر إلى هذه المعلمة ستُحاول دائمًا “التحويل” إلى سلسلة نصية إذا لم تكن بالفعل كذلك.

النوع ليس إلزاميًا ولكن يُشجع بشدة. تعريف نوع المعلمة سيُقلل بشكل كبير من الحالات غير المرغوب فيها في المستقبل. ثق بي.

الآن بعد تعريف المعلمة، يمكنك تشغيل أمر Install-Office باستخدام المعلمة Version وتمرير سلسلة النسخة إليها مثل 2013. القيمة المُمرة إلى معلمة Version تُشار إليها أحيانًا بـ معلمات الوسيط أو القيم.

Passing a Parameter to the Function
PS> Install-Office -Version 2013 I installed Office 2016. Yippee!

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

غير النص الثابت 2016 واستبدله بمتغير المعلمة Version وقم بتحويل علامات الاقتباس الفردية إلى علامات الاقتباس المزدوجة حتى يتم توسيع المتغير.

Modifying function code account for a parameter
function Install-Office { [CmdletBinding()] param( [Parameter()] [string]$Version ) Write-Host "I installed Office $Version. Yippee!" }

الآن يمكنك رؤية أن أي قيمة تمررها إلى معلمة Version ستمرر بعد ذلك إلى الدالة كمتغير $Version.

سمة المعلمة الإلزامية

استعد لأنني ذكرت أن السطر [Parameter()] كان مجرد “أنابيب وظيفية” وكان يتعين أن يعد الوظيفة للعمل الإضافي؟ إضافة سمات المعلمة للمعلمة هو العمل الإضافي الذي كنت أتحدث عنه سابقًا.

A parameter doesn’t have to be a placeholder for a variable. PowerShell has a concept called parameter attributes and parameter validation. Parameter attributes change the behavior of the parameter in a lot of different ways.

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

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

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

Using a mandatory parameter
function Install-Office { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Version ) Write-Host "I installed Office $Version. Yippee!" } PS> Install-Office cmdlet Install-Office at command pipeline position 1 Supply values for the following parameters: Version:

ستنتظر الوظيفة حتى تحدد قيمة لمعلمة Version. بمجرد فعلك ذلك والضغط على Enter، سيقوم PowerShell بتنفيذ الوظيفة والانتقال إلى الخطوة التالية. إذا قدمت قيمة للمعلمة، لن يطلب منك PowerShell إدخال المعلمة في كل مرة.

سمات التحقق من المعلمة في PowerShell

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

التعلم من خلال المثال

على سبيل المثال، في وظيفة Install-Office، قمت بتمرير القيمة 2013 لأنني كنت أعلم أنه سيعمل. لقد كتبت الشفرة! أنا أفترض (لا تفعل هذا في الشفرة!) أنه من الواضح أن أي شخص يعرف أي شيء سيحدد الإصدار كـ 2013 أو 2016. حسنًا، ما هو واضح لك قد لا يكون واضحًا للأشخاص الآخرين.

إذا كنت تريد أن تصبح فنيًا حول الإصدارات، فمن المحتمل أن يكون من الأدق تحديد الإصدار 2013 كـ 15.0 و 2016 كـ 16.0 إذا كانت مايكروسوفت لا تزال تستخدم نظام الإصدارات الذي كانت تستخدمه في الماضي. ولكن ماذا لو، نظرًا لأنك تفترض أنهم سيحددون إصدار 2013 أو 2016، لديك الشفرة داخل الوظيفة التي تبحث عن مجلدات بهذه الإصدارات أو شيء آخر؟

أدناه مثال على حالة يمكن أن تكون فيها تستخدم السلسلة $Version في مسار ملف. إذا قام شخص بتمرير قيمة لا تكمل اسم مجلد Office2013 أو Office2016، فسيفشل الأمر أو سيفعل شيئًا أسوأ، مثل إزالة مجلدات غير متوقعة أو تغيير أشياء لم تكن تتوقعها.

Assuming Parameter Values
function Install-Office { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Version ) Get-ChildItem -Path "\\SRV1\Installers\Office$Version" } PS> Install-Office -Version '15.0' Get-ChildItem : Cannot find path '\SRV1\Installers\Office15.0' because it does not exist. At line:7 char:5 Get-ChildItem -Path "\\SRV1\Installers\Office$Version" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CategoryInfo : ObjectNotFound: (\SRV1\Installers\Office15.0:String) [Get-ChildItem], ItemNotFoundExcep tion FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

لتقييد المستخدم فيما تتوقع منه إدخاله، يمكنك إضافة بعض التحقق من صحة المعلمات في PowerShell.

استخدام سمة التحقق من صحة المعلمات ValidateSet

هناك أنواع مختلفة من التحقق من صحة المعلمات التي يمكنك استخدامها. للحصول على قائمة كاملة، قم بتشغيل Get-Help about_Functions_Advanced_Parameters. في هذا المثال، ربما ستكون سمة ValidateSet

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

يمكنك إضافة سمات التحقق من صحة المعلمات مباشرة تحت الكلمة الأصلية Parameter. في هذا المثال، داخل قوسي سمة المعلمة، لديك مصفوفة من العناصر؛ 2013 و 2016. تخبر سمة التحقق من صحة المعلمات PowerShell أن القيم الوحيدة التي يمكن قبولها لـ Version هي 2013 أو 2016. إذا حاولت تمرير شيء خارج مجموعة القيم، ستتلقى خطأً يُخطِرك بأن لديك خيارات محددة فقط.

Using the ValidateSet parameter validation attribute
function Install-Office { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateSet('2013','2016')] [string]$Version ) Get-ChildItem -Path "\\SRV1\Installers\Office$Version" } PS> Install-Office -Version 15.0 Install-Office : Cannot validate argument on parameter 'Version'. The argument "15.0" does not belong to the set "2013,2016" specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again. At line:1 char:25 Install-Office -Version 15.0 ~~~~ CategoryInfo : InvalidData: (:) [Install-Office], ParameterBindingValidationException FullyQualifiedErrorId : ParameterArgumentValidationError,Install-Office

السمة ValidateSet هي سمة التحقق الشائعة للاستخدام. للحصول على تفصيل كامل حول جميع الطرق التي يمكن بها تقييد قيم المعلمة، يرجى الاطلاع على موضوع المساعدة Functions_Advanced_Parameters عند تشغيل Get-Help about_Functions_Advanced_Parameters.

مجموعات المعلمات

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

تحتاج إلى مجموعات المعلمات.

يمكن تجميع المعلمات في مجموعات يمكن استخدامها فقط مع معلمات أخرى في نفس المجموعة. باستخدام الوظيفة أدناه، يمكنك الآن استخدام كل من معلمة Version ومعلمة Path للوصول إلى مسار المثبت.

function Install-Office {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateSet('2013','2016')]
        [string]$Version,
        
        [Parameter(Mandatory)]
        [string]$Path
    )
    
    if ($Version) {
        Get-ChildItem -Path "\\SRV1\Installers\Office$Version"
    } elseif ($Path) {
        Get-ChildItem -Path $Path
    }
}

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

function Install-Office {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ParameterSetName = 'ByVersion')]
        [ValidateSet('2013','2016')]
        [string]$Version,
        
        [Parameter(Mandatory, ParameterSetName = 'ByPath')]
        [string]$Path
    )
    
    if ($Version) {
        Get-ChildItem -Path "\\SRV1\Installers\Office$Version"
    } elseif ($Path) {
        Get-ChildItem -Path $Path
    }
}

من خلال تعريف اسم مجموعة معلمات على كل معلمة، يتيح لك ذلك التحكم في مجموعات المعلمات معًا.

المجموعة الافتراضية للمعلمات

ماذا لو حاول المستخدم تشغيل Install-Office بدون معلمات؟ لم يتم احتساب ذلك، وستظهر لك رسالة خطأ ودية.

No parameter set

لحل هذه المشكلة ، ستحتاج إلى تحديد مجموعة معلمات افتراضية داخل منطقة CmdletBinding(). هذا يخبر الوظيفة بأن تختار مجموعة معلمات لاستخدامها إذا لم يتم استخدام معلمات بوضوح بتغيير [CmdletBinding()] إلى [CmdletBinding(DefaultParameterSetName = 'ByVersion')]

الآن ، عند تشغيل Install-Office ، سيطلب تحديد معلمة Version لأنه سيستخدم تلك المجموعة من المعلمات.

إدخال الأنابيب

في الأمثلة التي تم ذكرها حتى الآن ، كنت تقوم بإنشاء وظائف مع معلمة PowerShell التي يمكن تمريرها فقط باستخدام بناء الجملة النمطية -ParameterName Value. ولكن ، كما تعلمت بالفعل ، يحتوي PowerShell على أنبوب مباشر يسمح لك بتمرير الكائنات بسلاسة من أمر واحد إلى آخر دون استخدام بناء الجملة “النمطية”.

عند استخدام الأنبوب ، تقوم بـ “ربط” الأوامر معًا باستخدام رمز الأنبوب | الذي يتيح للمستخدم إرسال ناتج أمر مثل Get-Service إلى Start-Service كاختصار لتمرير معلمة Name إلى Start-Service.

الطريقة “القديمة” باستخدام حلقة

في الوظيفة المخصصة التي تعمل عليها ؛ تقوم بتثبيت Office ولديك معلمة Version. لنفترض أن لديك قائمة بأسماء الكمبيوتر في ملف CSV في صف واحد مع إصدار Office الذي يجب تثبيته عليها في الصف الثاني. يبدو ملف CSV مثل هذا:

ComputerName,Version
PC1,2016
PC2,2013
PC3,2016

تود تثبيت إصدار Office الذي يتوافق مع كل كمبيوتر على ذلك الكمبيوتر.

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

Adding the ComputerName parameter
function Install-Office { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateSet('2013','2016')] [string]$Version, [Parameter()] [string]$ComputerName ) <# ## الاتصال بالنظام عن بعد مع بعض الرموز هنا Invoke-Command -ComputerName $ComputerName -ScriptBlock { ## افعل شيئًا لتثبيت إصدار الأوفيس على هذا الكمبيوتر Start-Process -FilePath 'msiexec.exe' -ArgumentList 'C:\Setup\Office{0}.msi' -f $using:Version } #> Write-Host "I am installing Office version [$Version] on computer [$ComputerName]" }

بمجرد إضافة معلمة ComputerName إلى الوظيفة؛ يمكنك جعل هذا يحدث عن طريق قراءة ملف CSV وتمرير قيم اسم الكمبيوتر والإصدار إلى وظيفة Install-Office.

$computers = Import-Csv -Path 'C:\ComputerOfficeVersions.csv'
foreach ($pc in $computers) {
    Install-Office -Version $_.Version -ComputerName $_.ComputerName
}

بناء مدخل الأنبوبة للمعلمات

هذه الطريقة في قراءة صفوف CSV واستخدام حلقة لتمرير خصائص كل صف إلى الوظيفة هي الطريقة “القديمة” للقيام بذلك. في هذا القسم، تريد التخلي عن حلقة foreach تمامًا واستخدام الأنبوبة بدلاً من ذلك.

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

No function pipeline input defined
PS> Import-Csv -Path 'C:\ComputerOfficeVersions.csv' | Install-Office

يمكنك الافتراض بما تشاء، ولكن هذا لا يجعل الأمر يعمل. نحن نحصل على استدعاء لمعلمة Version عندما تعلم أن Import-Csv يرسلها كخاصية للكائن. لماذا لا يعمل؟ لأنك لم تضف أي دعم للأنابيب بعد.

هناك نوعان من إدخال الأنابيب في وظيفة PowerShell؛ بالقيمة (الكائن بأكمله) و باسم الخاصية (خاصية كائن واحد). ما هو الطريقة التي تعتقد أنها الأفضل لربط إخراج Import-Csv بإدخال Install-Office؟

دون أي إعادة ترتيب على الإطلاق، يمكنك استخدام طريقة ByPropertyName لأن Import-Csv بالفعل يعيد الخصائص Version و ComputerName لأنها أعمدة في ملف CSV.

إضافة دعم للأنابيب إلى وظيفة مخصصة أسهل بكثير مما قد تعتقد. إنها مجرد سمة للمعلمة تُمثل بإحدى الكلمات الرئيسية؛ ValueFromPipeline أو ValueFromPipelineByPropertyName.

في المثال، ترغب في ربط خصائص ComputerName و Version التي يعيدها Import-Csv بمعلمات Version و ComputerName في Install-Office لذا ستستخدم ValueFromPipelineByPropertyName.

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

Adding Pipeline Support
function Install-Office { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [ValidateSet('2013','2016')] [string]$Version, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string]$ComputerName ) <# ## الاتصال بالجهاز عن بُعد باستخدام بعض الشيفرة الخاصة هنا Invoke-Command -ComputerName $ComputerName -ScriptBlock { ## قم بتنفيذ الإجراءات اللازمة لتثبيت إصدار Office على هذا الكمبيوتر Start-Process -FilePath 'msiexec.exe' -ArgumentList 'C:\Setup\Office{0}.msi' -f $using:Version } #> Write-Host "I am installing Office version [$Version] on computer [$ComputerName]" }

يبدو ذلك غريبًا. تم تشغيلها فقط للصف الأخير في ملف CSV. ما الذي يحدث؟ تم تنفيذ الوظيفة فقط للصف الأخير لأنك تجاوزت مفهومًا غير مطلوب عند بناء الوظائف بدون دعم الأنابيب.

لا تنسى كتلة العمليات!

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

يمكنك نظريًا إضافة كتل أخرى مثل begin و end أيضًا، ولكن الناس الذين يكتبون السكربتات لا يستخدمونها بشكل متكرر.

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

Adding the process block
function Install-Office { [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipelineByPropertyName)] [ValidateSet('2013','2016')] [string]$Version, [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string]$ComputerName ) process { <# ## الاتصال بالجهاز عن بُعد باستخدام بعض الشيفرة الخاصة هنا Invoke-Command -ComputerName $ComputerName -ScriptBlock { ## قم بتنفيذ الإجراءات اللازمة لتثبيت إصدار Office على هذا الكمبيوتر Start-Process -FilePath 'msiexec.exe' -ArgumentList 'C:\Setup\Office{0}.msi' -f $using:Version } #> Write-Host "I am installing Office version [$Version] on computer [$ComputerName]" } }

الآن يمكنك أن ترى أن خصائص Version و ComputerName لكل كائن تم إرجاعه من Import-Csv تم تمريرها إلى Install-Office و مرتبطة بمعلمات Version و ComputerName.

الموارد

للتعمق أكثر في كيفية عمل معلمات الوظيفة، تحقق من مدونتي حول وظائف PowerShell.

I also encourage you to check my Pluralsight course entitled Building Advanced PowerShell Functions and Modules for an in-depth breakdown of everything there is to know about PowerShell functions, function parameters, and PowerShell modules.

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