Master the PowerShell WhatIf Parameter

لا أختبر سكربتاتي دائمًا ، ولكن عندما أفعل ذلك ، أقوم بذلك في الإنتاج

لا تكذب. لقد فعلتها من قبل. جميعنا قد فعلنا ذلك في وقت ما. لكنه لا يحتاج إلى أن يكون خطيرًا عند تشغيل سكربتات PowerShell في الإنتاج. فقط تذكر استخدام معلمة PowerShell المدمجة المسماة “WhatIf”!

لن يكون من الجيد أن تعرف ما ستفعله أمر PowerShell ذلك قبل أن يجري تغييرات على بيئتك؟ تخيل أن تكون قادرًا على أن تسأل الأمر الخاص بك “ماذا ستفعل إذا قمت بتشغيله؟” يمكنك استخدام المعلمة WhatIf.

تتضمن جميع الأوامر المحملة مسبقًا لـ PowerShell معلمة تسمى WhatIf. تساعدك هذه المعلمة في تقييم ما إذا كان الأمر سيعمل كما تتوقع أم سيبدأ في القيام بكارثة نووية.

المعلمة اليدوية WhatIf ليست متاحة فقط مع جميع الأوامر المدمجة ولكن أيضًا مع السكربتات ووظائف الأكواد المتقدمة أيضًا! إذا كان سينتج عن كودك تغييرات في بيئتك ، فلديك فائدة من آلية الحماية في حال قررت تنفيذها.

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

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

يرجى ملاحظة أنني سأستخدم برنامج Visual Studio Code 1.38 (أغسطس 2019) على جهاز يعمل بنظام التشغيل Windows 10 في هذه المقالة.

معلمة WhatIf في PowerShell: التعريف

باختصار، المعامل WhatIf هو معامل مدمج من نوع التبديل المتاح مع جميع الوظائف المتقدمة وcmdlets (من خلال إضافة كلمة CmdletBinding في سكربتات ووظائف PowerShell). عند استخدامه، يقوم الأمر بتقديم التأثير المتوقع للأمر إلى وحدة التحكم، ولكنه لا ينفذ الأمر بالفعل.

جميع cmdlets والوظائف المتقدمة تحتوي على معامل WhatIf المتاح. في هذه المقالة، سنقوم بتوضيح هذا المعامل باستخدام cmdlets Get-Service، Stop-Service، و New-Item.

التحقق من دعم PowerShell لـ WhatIf

إذا كنت غير متأكد مما إذا كان الأمر معين يدعم WhatIf، يوجد طريقتان سريعتان للتحقق.

استخدام Get-Command

يمكنك استخدام الأمر Get-Command لعرض بيانات الأمر باستخدام المعامل Syntax كما هو موضح أدناه. إذا رأيت مرجعًا لـ -WhatIf، فهذا يعني أن WhatIf مدعوم.

Get-Command <CommandName> -Syntax

استخدام الإكمال التلقائي بالعلامة التبويبية

يمكنك أيضًا التحقق من دعم معامل WhatIf باستخدام الإكمال التلقائي بالعلامة التبويبية. ما عليك سوى كتابة الأمر الذي ترغب في التحقق منه في وحدة التحكم PowerShell تليه مسافة وشرطة وحرف “Wh” ومفتاح التبويب.

إذا ظهر معامل WhatIf، فذلك يعني أن الأمر يحتوي على معامل WhatIf.

PS> <CommandName> -Wh[tab]

استخدام معامل PowerShell WhatIf مع cmdlets

هناك العديد من الطرق المختلفة التي يمكنك الاستفادة من معلمة WhatIf. في هذا القسم، ستتعلم كيف يمكنك البدء في استخدام المعلمة WhatIf على الفور باستخدام cmdlets المدمجة.

إنشاء ملف

كجميع cmdlets، يحتوي cmdlet New-Item على معلمة WhatIf. في هذا المثال، ستستخدم cmdlet New-Item لإنشاء ملف بالاسم newfile1.txt في نفس دليل العمل.

إذا قمت بتشغيل الأمر أدناه، فسيتم إنشاء الملف المسمى newfile.txt.

PS51> New-Item -ItemType File -Path .\newfile1.txt

ولكن ماذا لو أن هذا الأمر ينشئ ملفًا يمكن أن يتسبب في مشكلة إذا تم إنشاؤه بنجاح؟ لا توجد مشكلة. يمكنك إضافة معلمة WhatIf في النهاية.

New-Item -ItemType File -Path .\newfile1.txt -WhatIf

إيقاف خدمة

يمكنك أيضًا استخدام معلمة WhatIf مع cmdlet Stop-Service. في هذا المثال، ستحصل على قائمة بأول خمس خدمات وإيقاف تشغيلها باستخدام أمر Stop-Service. لكنك لست كذلك.

بدلاً من ذلك، سترى رسالة إخراج في وحدة التحكم PowerShell تخبرك بالخدمات التي كان سيتم إيقاف تشغيلها بواسطة cmdlet Stop-Service.

PS51> (Get-Service)[0..4] | Stop-Service -WhatIf

تغيير سلوك معلمة WhatIf في PowerShell على نطاق عام

في هذه المرحلة، يجب أن تعرف أن استخدام معلمة WhatIf مع cmdlet أو وظيفة متقدمة يحاكي فقط العملية. أنت تؤثر على سلوك WhatIf على مستوى الأمر.

يمكن أيضًا تعيين سلوك WhatIf على مستوى أعلى يؤثر على جميع الأوامر عن طريق تلاعب بالمتغير التلقائي $WhatIfPreference.

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

يمكنك اختبار هذا عن طريق تغيير قيمة $WhatIfPreference إلى True باستخدام $WhatIfPreference = $true. يمكنك أن ترى أدناه باستخدام New-Item بدون معلمة WhatIf يتصرف الآن كما لو تم تمرير المعلمة.

PS51> $WhatIfPreference = $true

إذا قمت بتغيير $WhatIfPreference إلى True، لا تنسى تغييره مرة أخرى إلى False باستخدام $WhatIfPreference = $false.

في هذا القسم ، تعلمت كيفية استخدام دعم WhatIf مع cmdlets الموجودة. في الإجراء التالي ، ستتعلم كيفية بناء دعم WhatIf في النصوص البرمجية والوظائف المخصصة لك.

تنفيذ دعم Powershell WhatIf في الوظائف

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

الطريقة الخاطئة: لا تعيد اختراع العجلة

ليس من النادر أن يقوم مطورو النصوص بإعادة اختراع العجلة وتنفيذ دعمهم الخاص لـ WhatIf باستخدام بعض المنطق if/then. فيما يلي يمكنك رؤية مثال.

لاحظ أن المطور قام بتعريف مفتاح التبديل الخاص بهم لـ WhatIf. ثم، باستخدام قيمة ذلك المعلمة، قاموا ببناء منطق if/then للتعامل مع السياق عند استخدام معلمة WhatIf أو عدم استخدامها.

Function Remove-LogFile {
    param (
        [Parameter(Mandatory)]
        [string]$name,

        [switch]$WhatIf
    )
    
    if ($WhatIf.IsPresent) { # مفتاح WhatIf مفعل.
        Write-Host "WhatIf: I will remove the log file ""$name""" -ForegroundColor Yellow
    } else {
        # مفتاح WhatIf معطل.
        Write-Host "Delete log file ""$name""" -ForegroundColor Green
    }
}

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

PS51> Remove-LogFile -name log.txt -WhatIf

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

بدلاً من ذلك، لا تعيد اختراع العجلة واستخدم الكلمة الأساسية SupportsShouldProcess مع الشفرة $PSCmdlet.ShouldProcess(). هذا سيظهر قريبًا.

القيام بالأمر بالطريقة الصحيحة: استخدام SupportsShouldProcess

جميع الوظائف التي تستخدم الكلمة الأساسية [CmdletBinding()] تجعلها “متقدمة”. تضيف هذه الكلمة الأساسية إمكانات مختلفة للوظيفة بما في ذلك دعم WhatIf.

تدعم جميع الوظائف المتقدمة وظيفة WhatIf، ولكن من الأمر بك أن تستفيد منها. للقيام بذلك، يجب عليك استخدام الكلمة الأساسية SupportsShouldProcess بين قوسين [CmdletBinding()] أولاً كما هو موضح أدناه.

[CmdletBinding(SupportsShouldProcess)]

تسمح الوظيفة الآن لك باستدعاء طريقة ShouldProcess() على متغير الوظيفة $PSCmdlet لتحديد ما إذا تم تمرير معلمة WhatIf إلى الوظيفة أم لا. عند استخدام معلمة WhatIf، تعيد ShouldProcess() False. وإلا، ستعيد دائمًا True.

Function Remove-LogFile {
     [cmdletbinding(SupportsShouldProcess)]
     param (
         [Parameter(Mandatory)]
         [string]$name
     )
     if ($PSCmdlet.ShouldProcess($name)) {
         ## لم يتم استخدام معلمة -WhatIf. يجب أن تتم المعالجة العادية للوظيفة.
         Write-Host ("Delete log file " + $name) -ForegroundColor Green
     } else {
         ## تم استخدام معلمة -WhatIf. يجب ألا تتم المعالجة للوظيفة.
     }
 }
WHATIF PARAMETER USED SHOULDPROCESS() RESULT
True False
False True

الآن يمكنك أن ترى أدناه عند تنفيذ Remove-LogFile مع معامل WhatIf؛ فإنه يعرض نفس سلوك الأوامر المدمجة.

PS51> Remove-LogFile -name log.txt -WhatIf

الملخص

في هذه المقالة، تعرفت على معامل PowerShell WhatIf. يجب أن تفهم الآن كيف يعمل وما الفوائد التي يمكن أن يجلبها.

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

قراءة إضافية

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