عند كتابة سيناريو أو وظيفة PowerShell ، غالبًا ما ترغب في قبول إدخال المستخدم عبر المعلمات. إذا لم تقم بتحديد القيم التي تقبلها تلك المعلمات ، يمكنك أن تضمن أن هناك حالات ستتم تزويد قيم غير مناسبة. في هذه المقالة ، تعلم كيفية استخدام سمة التحقق من المعلمة ValidateSet في PowerShell للحد من تلك القيم إلى القيم التي تحددها فقط.
عند كتابة سيناريو أو وظيفة PowerShell ، يمكنك استخدام العديد من سمات التحقق المختلفة للتحقق من أن القيم المزودة للمعلمات مقبولة وتنبيه المستخدم إذا لم تكن كذلك.
يتركز هذا المقال على سمة التحقق ValidateSet. ستتعلم ما الذي يفعله ValidateSet ولماذا قد ترغب في استخدام ValidateSet في الكود الخاص بك وكيفية القيام بذلك. ستتعلم أيضًا عن ميزة الإكمال التلقائي التي يتم تمكينها بواسطة ValidateSet والتي ستساعد مستخدمي الكود الخاص بك على توفير قيم المعلمة الصحيحة.
ملخص موجز لسمة PowerShell ValidateSet
ValidateSet هو سمة المعلمة التي تتيح لك تعريف مجموعة من العناصر التي يتم قبولها فقط كقيمة لتلك المعلمة.
على سبيل المثال ، ربما لديك سيناريو محدد للعمل مع مراقبي نطاق Active Directory. يحتوي هذا السيناريو على معلمة تحدد اسم مراقب النطاق. هل لا يكون من المنطقي تحديد قائمة القيم المقبولة لأسماء المراقبين الفعليين للنطاق؟ ليس هناك سبب للسماح للمستخدم باستخدام “foobar” كقيمة عندما تعرف مسبقًا ما هي القيم التي يحتاجها السيناريو. يوفر لك ValidateSet تلك القدرة.
المتطلبات
سيكون هذا المقال درس تعليمي. إذا كنت تخطط لمتابعة، ستحتاج إلى ما يلي:
- محرر الشفرة المرئية أو أي محرر شفرة آخر. سأستخدم محرر الشفرة المرئية.
- على الأقل PowerShell 5.1 لمعظم الشفرة في هذا المقال. هناك قسم واحد يتطلب PowerShell 6.1 أو الأحدث وسأحدده عندما نصل إليه
جميع الشفرة في هذا المقال تم اختبارها في البيئات التالية:
Operating System | PowerShell Versions |
---|---|
Windows 7 SP1 | 5.1, Core 6.2 |
Windows 10 1903 | 5.1, Core 6.2 |
Linux Mint 19.2 | Core 6.2 |
لمساعدتك في شرح المفاهيم المتعلقة بـ ValidateSet ستقوم ببناء نص صغير يسمى Get-PlanetSize.ps1. هذا النص يعيد معلومات عن أحجام الكواكب في نظامنا الشمسي.
ستبدأ بنص بسيط وستقوم تدريجيًا بتحسين قدرته على التعامل مع إدخالات المستخدم النهائي وتسهيل اكتشاف قيم المعلمات الممكنة لهم.
البدء
للبدء، انسخ والصق الشفرة PowerShell أدناه في محرر النص المفضل لديك واحفظه باسم Get-PlanetSize.ps1.
قم بتشغيل النص من سطر الأوامر PowerShell ويجب أن تحصل على ما يلي:
مفيد ولكن ليس مرنًا للغاية؛ يتم إعادة المعلومات لكل كوكب، حتى إذا كنت تريد المعلومات فقط للمريخ.
ربما ترغب في القدرة على تحديد كوكب واحد بدلاً من إرجاع كلها. يمكنك القيام بذلك عن طريق إدخال معلمة. دعونا نلقي نظرة على كيفية تحقيق ذلك فيما يلي.
قبول الإدخال باستخدام معلمة
للسماح للنص بقبول معلمة ، أضف كتلة Param()
إلى أعلى النص. اسم العلامة هو Planet
. تظهر كتلة Param()
المناسبة كما يلي.
في المثال أدناه ، تضمن السطر [Parameter(Mandatory)]
دائمًا توفير اسم كوكب للنص. إذا كان الاسم مفقودًا ، سيطلب النص واحد.
أبسط طريقة لدمج هذه المعلمة Planet
في النص هي تغيير السطر $planets.keys | Foreach-Object {
إلى $Planet | Foreach-Object {
. الآن لا تعتمد على الجدول الديناميكي المعرف سابقًا ولكن بدلاً من ذلك تقرأ قيمة معلمة Planet
.
الآن إذا قمت بتشغيل النص وحددت كوكبًا باستخدام معلمة Planet
، سترى معلومات حول ذلك الكوكب الخاص بك.
ممتاز. هل اكتمل النص؟ ربما لا.
الخيارات مفتوحة جدًا
ماذا يحدث إذا حاولت العثور على قطر الكوكب Barsoom باستخدام Get-PlanetSize.ps1؟
همم، هذا غير صحيح. Barsoom ليس على قائمة الكواكب ، ولكن النص يعمل على أي حال. كيف يمكننا إصلاح هذا؟
المشكلة هنا هي أن السكربت يقبل أي مدخل ويستخدمه، بغض النظر عما إذا كانت قيمة صالحة أم لا. يحتاج السكربت إلى طريقة لتحديد القيم التي يتم قبولها لمعلمة Planet
. ادخل ValidateSet!
ضمان استخدام قيم معينة فقط
A ValidateSet list is a comma-separated list of string values, wrapped in single or double-quotes. Adding a ValidateSet attribute to a script or function parameter consists of adding a line of text to the Param()
block, as shown below. Replace the Param()
block in your copy of Get-PlanetSize.ps1 with the one below and save the file.
جرب تشغيل السكربت مرة أخرى باستخدام Barsoom كمعلمة Planet
. الآن يتم إرجاع رسالة خطأ مفيدة. الرسالة محددة في ما الذي حدث خطأ وتوفر حتى قائمة من القيم الممكنة للمعلمة.
جعل PowerShell تفحص ValidateSet حساسية لحالة الأحرف
بشكل افتراضي، يكون سمة ValidateSet غير حساسة لحالة الأحرف. هذا يعني أنها ستسمح بأي سلسلة نصية مهما كانت معرفة في القائمة المسموح بها بأي نظام لحالة الأحرف. على سبيل المثال، سيقبل المثال أعلاه Mars
بسهولة تامة كما سيقبل mars
. إذا لزم الأمر، يمكنك أن تجبر ValidateSet على أن تكون حساسة لحالة الأحرف عن طريق استخدام الخيار IgnoreCase
.
الخيار IgnoreCase
في ValidateSet، سمة التحقق، تحدد ما إذا كانت القيم الموردة للمعلمة تتطابق بالضبط مع قائمة القيم الصالحة. بشكل افتراضي، يتم تعيين IgnoreCase
إلى $True
(تجاهل الحالة). إذا قمت بتعيينه إلى $False
، فإن توريد mars كقيمة لمعلمة Planet
لـ Get-PlanetSize.ps1
سيولد رسالة خطأ.
تستخدم الخيار IgnoreCase
عن طريق تعيين قيمة $true
له في نهاية القائمة من القيم الصالحة كما هو موضح أدناه.
الآن عندما تحاول استخدام قيمة لـ Planet
التي ليست بالضبط مثل القيمة في القائمة، ستفشل عملية التحقق.
استخدام الاكمال التلقائي بالتبويب
ميزة أخرى لاستخدام ValidateSet هي أنه يمنحك الاكمال التلقائي بالتبويب. هذا يعني أنه يمكنك التنقل خلال القيم الممكنة لمعلمة باستخدام مفتاح TAB. هذا يحسن بشكل كبير من قابلية استخدام نص أو وظيفة، خاصةً من الوحدة التحكم.
في الأمثلة أدناه، هناك بعض الأشياء التي يجب ملاحظتها:
- يعيد الاكمال بالتبويب إلى القيمة الأولى بعد عرض الأخيرة.
- تُعرض القيم بترتيب أبجدي، على الرغم من أنها ليست مُدرجة في ValidateSet بترتيب أبجدي.
- كتابة الحرف الأول والضغط على TAB يقيّد القيم المُعرضة بالاكمال التلقائي بالتبويب إلى تلك التي تبدأ بهذا الحرف.


يمكنك أيضًا الاستفادة من اكمال التلقائي بالتبويب في بيئة كتابة النصوص المتكاملة لـ PowerShell (ISE)، كما هو موضح في المثال أدناه. تُظهر ميزة Intellisense في ISE لك قائمة القيم الممكنة في صندوق اختيار جميل.
تُعيد Intellisense جميع القيم التي تحتوي على الحرف الذي تكتبه، بدلاً من تلك التي تبدأ به.

الآن بعد أن غطينا سمات التحقق ValidateSet كما هي في Windows 5.1، دعونا نلقي نظرة على ما تم إضافته في PowerShell Core 6.1 ونرى ما إذا كان ذلك يمكن أن يعطي نصنا المزيد من إمكانيات التحقق.
فهم التغييرات على ValidateSet في PowerShell 6.1
بمجرد وصول PowerShell Core 6.1، تمت إضافة قدرات جديدة إلى سمات التحقق ValidateSet:
- خاصية ErrorMessage
- استخدام الفئات في ValidateSet من خلال الوصول إلى
System.Management.Automation.IValidateSetValuesGenerator
خاصية ErrorMessage
الرسالة الخطأ الافتراضية التي تظهر عند توفير اسم كوكب غير صحيح لـ Get-PlanetSize.ps1 مفيدة، ولكنها قليلة الوضوح:
استخدم خاصية ErrorMessage
لسمة التحقق ValidateSet
لتعيين رسالة خطأ مختلفة، كما هو موضح في المثال أدناه. يتم استبدال {0}
تلقائيًا بالقيمة المقدمة، ويتم استبدال {1}
تلقائيًا بقائمة القيم المسموح بها.
استبدل كتلة Param()
في ملف النص البرمجي واحفظه. ثم حاول Get-PlanetSize.ps1 -Planet Barsoom
مرة أخرى. لاحظ أدناه أن الخطأ أقل كلامًا وأكثر وضوحًا.
بعد ذلك، تحقق من طريقة جديدة لتحديد القيم المقبولة في ValidateSet عبر PowerShell class.
فئات PowerShell
الأنواع المخصصة، المعروفة في PowerShell بأسماء الفئات، كانت متاحة منذ الإصدار 5. مع وصول PowerShell Core 6.1، هناك ميزة جديدة تسمح باستخدام فئة لتوفير القيم لـ ValidateSet.
استخدام فئة يسمح لك بالتغلب على القيد الرئيسي لـ ValidateSet – وهو أنها ثابتة. وهذا يعني أنها مضمنة كجزء من الوظيفة أو النص، ويمكن تغييرها فقط عن طريق تحرير النص نفسه.
الميزة الجديدة التي تعمل مع ValidateSet هي القدرة على استخدام فئة System.Management.Automation.IValidateSetValuesGenerator. يمكننا استخدام هذا كقاعدة لفئاتنا الخاصة باستخدام التوريث. للعمل مع ValidateSet، يجب أن تستند الفئة إلى System.Management.Automation.IValidateSetValuesGenerator ويجب أن تنفذ طريقة تسمى GetValidValues().
الطريقة GetValues() تُرجع قائمة القيم التي ترغب في قبولها. كتلة Param() مع القائمة الثابتة للكواكب التي تم استبدالها بفئة [Planet] ستبدو كما يلي. لن يعمل هذا المثال بعد. استمر في القراءة لتتعلم كيفية تنفيذ ذلك.
استخدام فئة لقائمة قيم ValidateSet: مثال حقيقي
لتوضيح استخدام فئة لقائمة قيمة ValidateSet، ستقوم بتعويض القائمة الثابتة للكواكب المستخدمة سابقًا بقائمة تم تحميلها من ملف نصي CSV. لن تحتاج بعد الآن إلى الحفاظ على قائمة ثابتة من القيم داخل النص نفسه!
إنشاء مصدر بيانات للفئة
أولاً، ستحتاج إلى إنشاء ملف CSV يحتوي على كل القيم الصالحة. للقيام بذلك، قم بنسخ ولصق هذه المجموعة من البيانات في ملف نصي جديد واحفظه كملف نصي بالاسم planets.csv في نفس المجلد الذي يحتوي على النص البرمجي Get-PlanetSize.ps1.
إضافة الفئة إلى النصي
أي فئة تُستخدم بواسطة ValidateSet يجب أن تكون قد تم تعريفها بالفعل قبل أن يحاول ValidateSet استخدامها. هذا يعني أن هيكل Get-PlanetSize.ps1 كما هو لن يعمل.
يجب تعريف الفئة [Planet] قبل أن يمكن استخدامها، لذلك يجب أن توضع في بداية النصي. تبدو تعريف الفئة الخاصة بالهيكل مناسبة على النحو التالي:
داخل الطريقة GetValidValues() للفئة، استخدم cmdlet Import-CSV لاستيراد ملف النص planets.csv الذي تم إنشاؤه مسبقًا. يتم استيراد الملف إلى متغير بنطاق عالمي يُسمى $planets، لذا يمكن الوصول إليه لاحقًا في النصي.
استخدم البيان return لإرجاع قائمة أسماء الكواكب عبر GetValidValues(). بعد هذه التغييرات، يجب أن تبدو الفئة الآن كما هو موضح أدناه.
بعد ذلك، احذف تعريف الجدول المتجانس $planets من النصي كما هو موضح أدناه. المتغير العالمي $planets الذي يتم ملؤه بواسطة الفئة [Planet] يحتوي على بيانات الكواكب بدلاً من ذلك.
الآن قم بلف الكود الأصلي المتبقي في وظيفة وسميه Get-PlanetDiameter للتمييز عن اسم النصي. ضع كتلة Param() التي كانت في بداية النصي داخل الوظيفة. استبدل القائمة الثابتة للكواكب بإشارة إلى الفئة [Planet] كما هو موضح أدناه.
استبدل السطر $output = "The diameter of planet {0} is {1} km" -f $_, $planets[$_]
بالسطرين التاليين. تسمح هذه السطور للنص بالبحث عن كوكب في مجموعة الكائنات التي تم إنشاؤها بواسطة Import-CSV
، بدلاً من الجدول الهاش الذي قمت بإنشائه سابقًا والذي قمت بإزالته من النص:
بعد هذه التغييرات، يجب أن يبدو النص النهائي كما يلي:
تذكر، من هذه النقطة فصاعدًا، يعمل النص فقط في PowerShell 6.1 أو الإصدارات الأحدث
الآن، كيفية استخدام هذا النص؟
تشغيل النص
لا يمكنك استخدام الإصدار الجديد من النص مباشرةً عن طريق تنفيذ النص. جميع الشفرة المفيدة مغلفة الآن في وظيفة. تحتاج إلى تحديد مصدر النص بدلاً من ذلك للسماح بالوصول إلى الوظيفة من داخل جلسة PowerShell.
بعد تحديد مصدر النص، لديك الآن الوصول إلى الوظيفة الجديدة Get-PlanetDiameter
في جلسة PowerShell، مع استكمال علامات التبويب.
“ما هو الفائدة من كل هذا العمل؟” أسمعك تسأل. “يبدو أن النص يعمل بنفس الطريقة، ولكن من الأصعب استخدام الشفرة!”
جرب هذا:
- افتح ملف
planets.csv
الذي قمت بإنشائه سابقًا. - أضف صفًا جديدًا بـ اسم وقطر جديد.
- احفظ ملف CSV.
في نفس الجلسة التي قمت فيها بتضمين النص الخاص بالسيناريو الخاص بك أصليًا، حاول البحث عن القطر الخاص بالكوكب الجديد باستخدام Get-PlanetDiameter
. إنه يعمل!
باستخدام فئة بهذه الطريقة يمنحنا العديد من الفوائد:
- قائمة القيم الصحيحة الآن مفصولة عن الكود نفسه، ولكن أي تغييرات على القيم في الملف يتم استقبالها من قبل السيناريو.
- يمكن صيانة الملف من قبل شخص لا يتصل بالسيناريو أبدًا.
- A more complex script could look up information from a spreadsheet, database, Active Directory or a web API.
كما يمكنك رؤية، الإمكانيات تقريبًا لا تنتهي عند استخدام فئة لتوفير قيم ValidateSet.
في الختام
لقد غطينا الكثير من المواضيع بينما بنينا Get-PlanetSize.ps1
، لذا دعنا نلخص.
في هذه المقالة تعلمت:
- ما هو سمة التحقق ValidateSet ولماذا قد ترغب في استخدامها
- كيفية إضافة ValidateSet إلى دالة PowerShell أو سيناريو
- كيف يعمل استكمال التبويب مع ValidateSet
- كيفية استخدام خاصية IgnoreCase للتحكم في ما إذا كانت ValidateSet حساسة للحالة
- كيفية استخدام خاصية ErrorMessage مع ValidateSet الخاص بك و PowerShell 6.1
- كيفية استخدام فئة لجعل ValidateSet ديناميكيًا مع PowerShell 6.1
ماذا تنتظر؟ ابدأ استخدام ValidateSet اليوم!
قراءة إضافية
Source:
https://adamtheautomator.com/powershell-validateset/