مسار وحدة PowerShell: كود قابل لإعادة الاستخدام دون نسخ ولصق

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

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

للوصول إلى مستوى أعلى من الوظائف ، يمكنك دمج هذه الوظائف معًا في وحدة.

A module is a collection of functions in a text file with a psm1 extension. There are some optional additions, such as a module manifest and comment-based or external help that may also be included. These will be covered later on.

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

I’ll be using Windows PowerShell 5.1 in this article. If you’re using an older version or PowerShell Core, your mileage may vary as to results you see.

التفاعل مع الوحدات

بمجرد فتح جلسة PowerShell للمرة الأولى ، ستبدأ بوحدتين. الأولى هي Microsoft.PowerShell.Utility التي تحتوي على العديد من الوظائف الأساسية لـ PowerShell التي تستخدمها بالفعل. الوحدة الأخرى هي PSReadline. يمكنك رؤية هذه الوحدات البدءية باستخدام الأمر Get-Module.

Listing modules with Get-Module

ومع ذلك ، هذه ليست قائمة كاملة بجميع الوحدات المتاحة. منذ PowerShell 3 ، سيتم استيراد الوحدات المثبتة حسب الحاجة. إذا كنت تستخدم نسخة قديمة من PowerShell ، فسيتعين عليك استخدام أمر Import-Module لاستيراد الوحدة قبل استخدام أي من الأوامر.

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

Importing modules with Import-Module

عندما تقوم بتشغيل أمر Get-Module، ستظهر لك جميع الوحدات التي تم استيرادها، ولن تظهر لك الوحدات التي لم يتم استيرادها بعد. يمكنك استخدام المعامل ListAvailable لعرض جميع الوحدات الأخرى المتاحة.

Listing all available modules with Get-Module -ListAvailable

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

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

قد يرغب كتاب الوحدة في إخفاء وظيفة لأنها تهدف لدعم وظائف أخرى وليست موجهة للمستخدم. لإخفاء وظيفة، سيقوم الكاتب بإستبعادها من مجموعة FunctionsToExport في التصريح. هنا يمكنك رؤية نظرة موسعة على خاصية ExportedCommands.

Viewing exported commands

استيراد الوحدات

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

استيراد الأوامر بشكل انتقائي

يمكنك استخدام Import-Module لاستيراد وظائف محددة فقط بدلاً من استيراد الوحدة النمطية بأكملها باستخدام معلمة Function. يمكن أن يوفر هذا الوقت عند استيراد الوحدات النمطية من الأنظمة البعيدة ، مثل وحدات Office 365.

جميع وحدات المستخدم

تُوضع الوحدات المثبتة لجميع المستخدمين في المجلد C:\Program Files\WindowsPowerShell\Modules. يحتوي هذا الدليل على العديد من الوحدات المضمنة مسبقًا بما في ذلك أي وحدات مثبتة باستخدام Install-Module باستخدام نطاق الافتراضي AllUsers.

وحدات المستخدم الحالي

إذا كنت تقوم بتثبيت وحدة نمطية وترغب فقط في أن يستخدمها مستخدم واحد ، فهناك نطاق CurrentUser. يضع ذلك ملفات الوحدة النمطية في مجلد المستندات الخاص بك في المسار C:\Users\<username>\Documents\WindowsPowerShell\Modules. يمكن أن يكون ذلك مفيدًا في بيئة تستخدم فيها إعادة توجيه المجلد مع مجلد المستندات.

في هذه الحالة ، يمكنك تثبيت وحدة نمطية على جهاز كمبيوتر واستخدامها على جهاز آخر لأنهما سيشتركان في نفس مجلد المستندات.

وحدات النظام

لإكمالها ، هناك أيضًا دليل للوحدات في المسار C:\Windows\System32\WindowsPowerShell\1.0\Modules. على الرغم من أنه من الناحية الفنية ، يمكن استيراد وحدة موجودة في هذا المسار بنفس طريقة استيراد الوحدات في المسارات الأخرى ، إلا أنه ليس مستحسنًا ، حيث يُحتفظ بهذا المسار لوحدات النظام التابعة لشركة مايكروسوفت.

التسمية مهمة

يمكنك وضع وحدتك يدويًا في أحد هذه المسارات لجعلها متاحة افتراضيًا مع جلسة جديدة ، ولكن يجب التأكد من اتباع التسمية المطلوبة للوحدات. يجب أن يكون اسم المجلد الذي توضع فيه ملفات الوحدة هو نفس اسم ملف الوحدة psm1 والتعريف psd1 إذا وجد.

باستخدام Get-Module -ListAvailable الذي تحدثنا عنه سابقًا ، يتم الإشارة إلى هذه المسارات. يمكنك رؤية جميع مسارات الوحدات باستخدام $env:PSModulePath -Split ';'. قد تلاحظ وجود مسارات أخرى في القائمة غير تلك المعروضة هنا. العديد من البرامج تضيف مسارات وحداتها الخاصة عند تثبيتها. أحد الأمثلة على ذلك هو SQL ، الذي يحتوي على وحداته الخاصة المضمنة في مسارات الوحدات الخاصة به.

Viewing module paths with $env:PSModulePath

هناك أيضًا بعض الوحدات التي يتعين تثبيتها باستخدام عملية مختلفة. أحد أمثلة ذلك هو وحدة ActiveDirectory. من Windows 7 إلى Windows 10 1803 ، كنت ستقوم بتثبيت هذا باستخدام أداة تثبيت Remote Server Administration Tools (RSAT).

في الإصدارات الأحدث من Windows 10 (1809+) ، هذا متاح فقط من خلال Features On Demand. تثبيت RSAT يقوم بتثبيت وحدات ActiveDirectory والكثير من الوحدات الأخرى التي يمكن استخدامها لإدارة أدوار Windows الأخرى. على أنظمة تشغيل خادم Windows ، يتم تثبيت هذه الوحدات من خلال Server Manager.

استيراد وحدات بعيدة (تمثيل ضمني)

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

استيراد وحدات بعيدة يستخدم أيضًا عندما لا يتم تثبيت الوحدة محليًا. هذا هو ما ستحصل عليه إذا لم يتم تثبيت وحدة ActiveDirectory محليًا، ولكن حاولت استيرادها.

Module not installed

لاستيراد وحدة بعيدة، يجب أولاً إنشاء PSSession. يمكنك استخدام New-PSSession لإنشاء الجلسة. ثم يمكنك استيراد الوحدة المتاحة على الجهاز البعيد باستخدام معامل PSSession مع Import-Module.

PS51> $AdminServer = New-PSSession -ComputerName $AdminServerName -Credential (Get-Credential)
PS51> Import-Module -Name ActiveDirectory -PSSession $AdminServer -Prefix 'Rmt'

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

إضافة بادئة للوحدة

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

إذا قمت بتشغيل أمر الاستيراد أعلاه وهذا ما ستراه عند النظر في الأوامر:

Viewing all available commands in a module

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

إزالة الوحدات

يمكنك أيضًا إزالة وحدة من الجلسة الحالية بدون استخدام Remove-Module. يقوم هذا بإزالة وحدة من الجلسة المحلية دون إزالة ملفات الوحدة. قد ترغب في استخدام هذا في حالة كنت تستخدم جلسة بعيدة لاستخدام وحدة. يمكنك استخدام Remove-Module لتنظيف الجلسة الخاصة بك ثم قطع الاتصال بالجلسة البعيدة.

Removing a module from the session

استخدام آخر لـ Remove-Module هو إذا كنت تجري تغييرات على وحدة ولا ترغب في تشغيل جلسة PowerShell جديدة. في هذه الحالة ، يمكنك استخدام Remove-Module تتبعها Import-Module لإعادة تحميله في جلستك. بدلاً من ذلك ، يمكنك استخدام معلمة Force مع Import-Module. سيتم إكمال عملية تفريغ وإعادة تحميل الوحدة بالنسبة لك.

ما يشكل وحدة PowerShell

A module can consist of one or more files. To meet the minimum requirements for a module, you must have a module file. This can be a PSM1 file or any other module file such as a binary module file. To build upon that, your psm1 should have functions defined in it, or it will not be much use to anyone.

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

تحتوي الوحدات على وظائف ذات تفكير متشابه

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

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

باستخدام هذه الإرشادات، إذا كانت لديك مجموعة من الوظائف التي تتعامل جميعها مع التفاعل مع سجل التسجيل، يمكن أن تكون لديك شيئًا مثل:

function Get-ATARegistryKey {...}

function Set-ATARegistryKey {...}

وحدة البيانات

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

هنا هو مثال للبيان الذي قد يكون لدينا لوحدة سجلنا:

#تعليمات وحدة الـ 'ATARegistry'
#تم إنشاؤها بواسطة: تايلر
#تم إنشاؤها في: 8/11/2019
@{
	#وحدة النص البرمجي أو ملف الوحدة الثنائية المرتبط بهذه التعليمات البرمجية.
	RootModule = 'ATARegistry'
	#رقم الإصدار لهذه الوحدة.
	ModuleVersion = '1.0'
	#الإصدارات المُدعَمَة
	#CompatiblePSEditions = @()
	#معرّف يستخدَم لتحديد هوية هذه الوحدة بشكل فريد
	GUID = 'fef619fa-016d-4b11-a09d-b222e094de3e'
	#مُؤلف هذه الوحدة
	Author = 'Tyler Muir'
	#شركة أو بائع هذه الوحدة
	CompanyName = 'Adam the Automator'
	#بيان حقوق النشر لهذه الوحدة
	Copyright = '(c) 2019 tyler. All rights reserved.'
	#وصف الوظائف المقدمة من قبل هذه الوحدة
	Description = 'This is a test module.'
	#الإصدار الأدنى لمحرك Windows PowerShell المطلوب لهذه الوحدة
	#PowerShellVersion = ''
	#اسم البرنامج المضيف Windows PowerShell المطلوب لهذه الوحدة
	#PowerShellHostName = ''
	#الإصدار الأدنى لبرنامج المضيف Windows PowerShell المطلوب لهذه الوحدة
	#PowerShellHostVersion = ''
	#الإصدار الأدنى لإطار العمل Microsoft .NET المطلوب لهذه الوحدة. هذا الشرط المسبق ساري لإصدار PowerShell Desktop فقط.
	#DotNetFrameworkVersion = ''
	#الإصدار الأدنى لـ common language runtime (CLR) المطلوب لهذه الوحدة. هذا الشرط المسبق ساري لإصدار PowerShell Desktop فقط.
	#CLRVersion = ''
	#هندسة المعالج المطلوبة لهذه الوحدة (لا شيء، X86، Amd64)
	#ProcessorArchitecture = ''
	#الوحدات التي يجب استيرادها إلى البيئة العامة قبل استيراد هذه الوحدة
	#RequiredModules = @()
	#التجمعات التي يجب تحميلها قبل استيراد هذه الوحدة
	#RequiredAssemblies = @()
	#ملفات النص البرمجي (.ps1) التي يتم تشغيلها في بيئة المتصل قبل استيراد هذه الوحدة.
	#ScriptsToProcess = @()
	#ملفات النص البرمجي من النوع (.ps1xml) التي يتم تحميلها عند استيراد هذه الوحدة
	#TypesToProcess = @()
	#ملفات التنسيق (.ps1xml) التي يتم تحميلها عند استيراد هذه الوحدة
	#FormatsToProcess = @()
	#وحدات للاستيراد كوحدات فرعية للوحدة المحددة في RootModule/ModuleToProcess
	#NestedModules = @()
	#الوظائف للتصدير من هذه الوحدة، لأداء أفضل، لا تستخدم العناصر المتعددة ولا تحذف الإدخال، استخدم مصفوفة فارغة إذا لم تكن هناك وظائف للتصدير.
	FunctionsToExport = @('Get-RegistryKey','Set-RegistryKey')
	#الأوامر للتصدير من هذه الوحدة، لأداء أفضل، لا تستخدم العناصر المتعددة ولا تحذف الإدخال، استخدم مصفوفة فارغة إذا لم تكن هناك أمر للتصدير.
	CmdletsToExport = @()
	#المتغيرات للتصدير من هذه الوحدةVariablesToExport = '*'
	#الأسماء المستعارة للتصدير من هذه الوحدة، لأداء أفضل، لا تستخدم العناصر المتعددة ولا تحذف الإدخال، استخدم مصفوفة فارغة إذا لم تكن هناك أسماء مستعارة للتصدير.
	AliasesToExport = @()
	#موارد DSC للتصدير من هذه الوحدة
	#DscResourcesToExport = @()
	#قائمة جميع الوحدات المعبأة مع هذه الوحدة
	#ModuleList = @()
	#قائمة جميع الملفات المعبأة مع هذه الوحدة
	#FileList = @()
	#بيانات خاصة لتمريرها إلى الوحدة المحددة في RootModule/ModuleToProcess. قد تحتوي أيضًا على جدول بيانات PSData مع بيانات الوحدة الفرعية الإضافية المستخدمة بواسطة PowerShell.
	PrivateData = @{
		PSData = @{
			#العلامات المُطبقة على هذه الوحدة. تساعد هذه العلامات في اكتشاف الوحدة في المعارض عبر الإنترنت.
			#Tags = @()
			#عنوان URL للترخيص لهذه الوحدة.
			#LicenseUri = ''
			#عنوان URL للموقع الرئيسي لهذا المشروع.
			#ProjectUri = ''
			#عنوان URL لأيقونة تمثل هذه الوحدة.
			#IconUri = ''
			#ملاحظات الإصدار لهذه الوحدة
			#ReleaseNotes = ''
		} 
		#نهاية جدول بيانات PSData
	} 
	#نهاية جدول بيانات خاصة
	#عنوان URI المساعدة لهذه الوحدة
	#HelpInfoURI = ''
	#البادئة الافتراضية للأوامر المُصدرة من هذه الوحدة. قم بتجاوز البادئة الافتراضية باستخدام Import-Module -Prefix.
	#DefaultCommandPrefix = ''
}

بينما قد يبدو هذا مرعبًا في البداية ، لديك Microsoft أداة سهلة الاستخدام يمكنك استخدامها لإنشاء وحدة نمطية. الأمر المضمن هو New-ModuleManifest. لتوليد الوحدة النمطية المعروضة أعلاه ، يمكنك استخدام:

PS51> New-ModuleManifest -Path .\Scripts\TestModule.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule 'TestModule.psm1' -FunctionsToExport @('Get-RegistryKey','Set-RegistryKey') -Description 'This is a test module.'

ملفات المساعدة الخارجية

قد ترى أيضًا ملفات مساعدة خارجية في بعض الوحدات النمطية. يمكن تحديدها بـ <اسم الوحدة النمطية>-Help.xml في نهاية اسم الملف. تحتوي هذه الملفات المساعدة الخارجية على نفس المعلومات التي يتم ضمها عادةً في المساعدة المستندة إلى الأوامر التي يمكنك العثور عليها في تعريف الوظيفة.

هذا سيتطلب أيضًا منك إضافة # .ExternalHelp <مسار الوحدة النمطية>-Help.xml إلى وظيفتك لجعلها تعمل بشكل صحيح عند استخدام الأمر Get-Help بعد استيراد الوحدة النمطية. عادةً ما يكون من الشائع رؤية ملفات مساعدة خارجية مع وحدات نمطية كبيرة جدًا وبسبب ذلك فهي خارج نطاق الشرح.

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

لنشر ملفات الوحدة النمطية غير القياسية بشكل صحيح ، يجب عليك تضمين الملفات الأخرى في معلمة FileList في وحدة نمطية الخاصة بك.

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

Requiring certain versions of PowerShell

PSRepositories

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

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

Default PowerShell NuGet repositories

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

إضافة PSRepositories

يمكنك أيضًا إضافة مستودعات خاصة بك. للثقة في PowerShell Gallery، يمكنك تشغيل Get-PSRepository -Name PSGallery | Set-PSRepository -InstallationPolicy Trusted أو يمكنك قبول التحذير في المرة الأولى التي تثبت فيها وحدة نمطية من PowerShell Gallery.

يمكن العثور على جميع الأوامر التي يمكنك استخدامها للتفاعل مع هذه المستودعات الشخصية لـ PowerShell في وحدة PowerShellGet. يمكنك رؤية الوظائف هنا:

Commands in the PowerShellGet module

قد يكون من الضروري تحديث وحدة PowerShellGet قبل التفاعل مع بعض المستودعات الخاصة.

العثور على الوحدات

ميزة رئيسية أخرى لاستخدام مستودع PowerShell هي القدرة على البحث عن الوحدات. يتم ذلك باستخدام أمر Find-Module. هناك طرق متعددة لتصفية البحث للعثور على ما تبحث عنه بالضبط، ولكن في الوقت الحالي يمكنك البحث عن وحدات VMware بهذا الشكل:

Finding modules on the PowerShell Gallery

سيتم عرض جميع الوحدات التي تبدأ بـ VMware. بينما يعود معظمها إلى VMware، يجب عليك النظر إلى سمة المؤلف لمعرفة من نشر الوحدة.

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

تثبيت الوحدات

لاستخدام أمر Install-Module، يجب أن يكون لديك مستودع PowerShell موثوق يستضيف الوحدة. يمكن أن يكون PowerShell Gallery أو مستودع آخر على الإنترنت PSRepository، أو موقع مضيف ذاتي. يمكنك توجيه البيانات من أمر Find-Module للتأكد من توفر الوحدة قبل تثبيتها بسهولة.

Finding modules installed from a PSRepository

يمكنك أيضًا تحديد إصدار الوحدة باستخدام معلمات MinimumVersion، MaximumVersion، أو RequiredVersion.

لرؤية جميع الوحدات المثبتة باستخدام Install-Module يمكنك استخدام Get-InstalledModule. ستقوم هذه الأمر بعرض جميع الوحدات المثبتة في نطاق AllUsers أو نطاق CurrentUser الخاص بك.

إلغاء تثبيت الوحدات

تمامًا مثلما يمكنك تثبيت وحدة، يمكنك أيضًا إلغاء تثبيت وحدة. إذا لم يتم تثبيت الوحدة عبر أمر Install-Module، فلن تتمكن من إلغاء تثبيتها باستخدام أمر Uninstall-Module.

Uninstalling modules installed from a PSRepository with Uninstall-Module

كما يمكنك أن ترى هنا، نحاول إلغاء تثبيت وحدة ActiveDirectory. نظرًا لأن هذه الوحدة لم تتم تثبيتها باستخدام Install-Module، ستتلقى خطأ عند محاولة استخدام Uninstall-Module. لإلغاء تثبيت هذه الوحدة، سيتعين علينا إلغاء تثبيتها من خلال عكس ما استخدمته لتثبيت الوحدة.

لرؤية إلغاء تثبيت ناجح لوحدة، يمكنك إلغاء تثبيت وحدة VMware.PowerCLI التي قمت بتثبيتها سابقًا.

Uninstalling a module downloaded from the PowerShell Gallery

على الرغم من أنك قمت بإلغاء تثبيت VMware.PowerCLI، يمكنك أن ترى أن هناك العديد من التبعيات التي تم تثبيتها. إذا كنت ترغب في إلغاء تثبيت جميع الوحدات، يمكننا استخدام Get-InstalledModule VMware.* | Uninstall-Module -Force.

السبب في صعوبة إلغاء تثبيت هذه الوحدة بشكل كامل هو أنها تحتوي على العديد من التبعيات. بالإضافة إلى ذلك، بعض هذه الوحدات هي تبعيات لبعضها البعض، وهذا هو السبب في ضرورة استخدام معامل Force.

تحديث الوحدات

الآن بعد أن تعرف كيفية تثبيت وإلغاء تثبيت وحدة، قد تتساءل عن كيفية تحديث وحدة قمت بتثبيتها.

تمامًا مثل العمليات الأخرى، إذا لم يتم تثبيت الوحدة باستخدام Install-Module، فلا يمكنك تحديثها باستخدام أوامر PowerShell. يمكنك استخدام Update-Module لتحديث وحدة إلى أحدث إصدار، أو إلى إصدار أحدث محدد.

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

Updating modules with Update-Module

فحص/حفظ وحدة

أحد الأوامر القليلة المستخدمة جدًا والتي تكون مفيدة جدًا عند فحص الوحدات قبل الاستخدام هو Save-Module. باستخدام هذا الأمر، يمكنك تنزيل وحدة إلى مسار دون تثبيتها.

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

Downloading modules with Save-Module

في هذا المثال، تم تنزيل وحدة VMware.PowerCLI، بالإضافة إلى جميع التبعيات. إليك ما يظهر في مجلد VMware.PowerCLI:

VMware.PowerCLI module contents

هذا مثال جيد يوضح كيف يوجد أحيانًا ملفات وحدة غير قياسية مدرجة في الوحدة مثل اتفاقية ترخيص المستخدم النهائي.

كتابة وحدة خاصة بك

لقد رأيت الآن كيفية التفاعل مع وحدة أخرى لشخص آخر. الآن تريد أن تتعلم كيفية إنشاء وحدة خاصة بك حتى تتمكن من تحسين كودك لقابلية التوسع

إنشاء ملفات القالب

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

PS51> New-Item -Path .\Scripts -Name ATARegistry -ItemType Directory
PS51> New-Item -Path .\Scripts\ATARegistry -Name ATARegistry.psm1

الآن تريد أيضًا استخدام تعليمة برمجية ، ستحتاج أيضًا إلى تسميتها بنفس الاسم الذي لدى الحاوية وملف الوحدة.

PS51> New-ModuleManifest -Path .\Scripts\ATARegistry\ATARegistry.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule ATARegistry.psm1 -Description 'Used for interacting with registry keys'

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

تسجيل PSRepository

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

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

PS51> New-Item -Path C:\ -Name Repo -ItemType Directory
PS51> Register-PSRepository -Name 'LocalRepo' -SourceLocation 'C:\Repo' -PublishLocation 'C:\Repo' -InstallationPolicy Trusted

إذا كنت تقوم بتنزيل فقط من PSRepository ولم تقم بالنشر أبدًا ، فيمكنك استبعاد معلمة PublishLocation.

نشر وحدتك

نظرًا لأنك قد قمت بتعيين سياسة التثبيت على الوثوق، فلن تحصل على تأكيد للسماح بتثبيت وحدة من المستودع. الآن أن لديك PSRepository جديد متاح، يمكنك نشر وحدتك باستخدام Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo.

بعد نشر الوحدة الخاصة بك، يمكنك استخدام الأوامر من أعلاه للعثور على الوحدة وتثبيتها.

الآن بعد تثبيت الوحدة، يمكنك استخدام Get-Module لمشاهدة الوحدة المستوردة في الجلسة المحلية الخاصة بك. نظرًا لعدم إضافة أي وظائف إلى مصفوفة FunctionsToExport في الملف الوصفي، فإن خاصية ExportedCommands فارغة.

No exported commands

إضافة لوحدتك

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

function Get-ATARegistryKey {
    param (
        [string]$Path
    )
    Get-Item $Path
}

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

تصدير وظائف الوحدة

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

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

طالما لم تقم بتعريف مصفوفة فارغة، @()، لـ FunctionsToExport، يتم تصدير جميع الوظائف والمتغيرات والأسماء المستعارة بشكل افتراضي.

لحل هاتين المشكلتين، يمكنك تحديث ملف الوحدة الخاص بك على النحو التالي:

ModuleVersion = '1.1'
FunctionsToExport = 'Get-RegistryKey'

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

PS51> Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo.

اختيار بين FunctionsToExport و Export-ModuleMember

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

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

A few notes about Export-ModuleMember:

  • تعديل سلوك FunctionsToExport، وبالتالي فإن استخدام أمر Export-ModuleMember لا يؤثر عليه.
  • Export-ModuleMember لا يقوم بتصدير المتغيرات والأسماء المستعارة بدون تعريف صريح لها، على عكس FunctionsToExport الذي يقوم بتصدير تلك القيم.
  • يمكن استخدام عدة أوامر Export-ModuleMember وتراكمها بدلاً من الأخذ بالأسبقية.

إذا لم تتوقع تغييرات في قائمة الوظائف الخاصة بك، يعمل استخدام تكوين “FunctionsToExport” في تعريف الوحدة بشكل جيد، ولا يتطلب منك تصدير المتغيرات والاختصارات بشكل صريح.

تحديث الوحدة الخاصة بك

الخطوة الأخيرة ستكون تحديث الوحدة الخاصة بك في جلستك لتتمكن من استخدام الملفات المحدثة. باستخدام “Update-Module ATARegistry” ستقوم بتنزيل التحديث الذي قمت للتو بنشره في المستودع.

Exported commands now show up

الآن يمكنك أن ترى أن لديك النسخة الجديدة من الوحدة ويمكنك أن ترى الوظيفة التي قمت بتعريفها في التعريف.

بناء محتوى المساعدة

واحدة من الخيارات التي تم تجاوزها في وقت سابق هو نظام المساعدة المدمج في PowerShell. ربما قمت في وقت ما باستخدام “Get-Help” على وظيفة. يمكن إضافة هذه المعلومات بطريقتين رئيسيتين.

الطريقة الأولى هي إضافة تعليقات المساعدة المستندة إلى الوظيفة. عادةً ما يستخدمها كتاب الوحدات البرمجية العديد. الطريقة الأخرى هي استخدام ملف مساعدة خارجي. يمكنك استخدام المعامل “Full” لعرض كل ما يقدمه النظام من مساعدة.

Finding help with Get-Help

كما يمكنك أن ترى، هناك حقًا ليس هناك الكثير من المعلومات والمعلومات القليلة التي تحصل عليها على الأرجح لن تكون مفيدة لأي شخص.

يمكنك إضافة بعض التعليقات المستندة إلى ملف الوحدة الخاص بك لملء هذه الحقول في نظام المساعدة. يمكنك قراءة جميع الخيارات المتاحة للمساعدة المستندة بالتعليق عن طريق استخدام “Get-Help about_Comment_Based_Help”.

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

الآن تبدو وظيفتك على النحو التالي:

 function Get-RegistryKey {
	<#
.SYNOPSIS
يعيد مفتاح التسجيل باستخدام المسار المقدم.
.DESCRIPTION
تستخدم الوظيفة أمر Get-Item لإرجاع المعلومات لمفتاح التسجيل المقدم.
.PARAMETER Path
المسار الذي سيتم البحث فيه عن مفتاح التسجيل.
.EXAMPLE
Get-RegistryKey -Path 'HKLM:\HARDWARE\DESCRIPTION\System'
.INPUTS
System.String
.OUTPUTS
Microsoft.Win32.RegistryKey
.NOTES
هذه الوحدة هي مثال على كيفية يمكن أن تبدو وظيفة موثقة بشكل جيد.
.LINK
ATA Learning
#>
param( [string]$Path ) Get-Item $Path }

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

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

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

Getting full help content with Get-Help

في حالة ملف المساعدة الخارجي ، يتم إضافة نفس المعلومات ، ولكن يتم وضع المعلومات في ملف منفصل وربطه داخل الوظيفة.

إذا نظرت في مسار الوحدة AllUsers ، يمكنك رؤية إصدار الوحدة وجميع ملفات الوحدة التي قمت بتثبيتها.

Folder name is the module version

إذا عدت إلى مسار PSRepository الخاص بك C:\Repo الذي قمت بإنشائه سابقًا ، يمكنك رؤية مجموعة من ملفات NUPKG. سيكون هناك ملف لكل إصدار تم نشره. هذه هي الإصدارات المضغوطة لما قمت بنشره عند استخدام Publish-Module.

ملخص

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

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

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