ما هو Windows PowerShell وماذا يأكل؟ الجزء 4: العمل مع الكائنات والفئات المخصصة



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

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


PowerShell




ForEach-Object, Group-Object Measure-Object
.NET COM (New-Object)

PSCustomObject


PowerShell


تذكر أن الكائن عبارة عن مجموعة من حقول البيانات (الخصائص ، والأحداث ، وما إلى ذلك) وطرق معالجتها (الأساليب). يتم تحديد هيكلها حسب النوع ، والذي يعتمد عادةً على الفئات المستخدمة في النظام الأساسي الموحد. NET Core. من الممكن أيضًا العمل مع كائنات COM و CIM (WMI) و ADSI. هناك حاجة إلى الخصائص والأساليب لتنفيذ إجراءات مختلفة على البيانات ، بالإضافة إلى PowerShell ، يمكن تمرير الكائنات كوسيطات للدوال و cmdlets ، وتعيين قيمها للمتغيرات ، وهناك أيضًا آلية لتأليف الأوامر (خط الأنابيب أو خط الأنابيب). يقوم كل أمر في خط الأنابيب بتمرير مخرجاته إلى الأمر التالي بدوره - كائنًا تلو الآخر. للمعالجة ، يمكنك استخدام أوامر cmdlets المترجمة أو إنشاء وظائف متقدمة خاصة بكللقيام بمعالجة مختلفة مع الكائنات في خط الأنابيب: التصفية والفرز والتجميع وحتى تغيير هيكلها. يتميز نقل البيانات في هذا النموذج بميزة خطيرة: لا يحتاج فريق الاستلام إلى تحليل تدفق وحدات البايت (النص) ، ويتم استخراج جميع المعلومات الضرورية بسهولة من خلال الرجوع إلى الخصائص والأساليب المقابلة.

عرض بنية الكائن


على سبيل المثال ، قم بتشغيل أمر cmdlet Get-Process ، والذي يسمح لك بالحصول على معلومات حول العمليات قيد التشغيل في النظام:



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

Get-Process | Get-Member



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

Get-Process | Get-Member -MemberType Property

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

تصفية الكائنات


يتيح لك PowerShell توجيه الأنابيب التي تلبي حالة معينة:

Where-Object {   }

يجب أن تكون نتيجة تنفيذ كتلة البرنامج النصي في أقواس عامل التشغيل قيمة منطقية. إذا كان صحيحًا ($ true) ، فسيتم تمرير الكائن الذي أدخل أمر cmdlet Where-Object إلى أسفل خط الأنابيب ، وإلا سيتم حذفه (القيمة $ false). على سبيل المثال ، نقوم بإدراج خدمات Windows Server المتوقفة ، أي أولئك الذين لديهم خاصية الحالة تم تعيينهم على متوقف:

Get-Service | Where-Object {$_.Status -eq "Stopped"}



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

Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member



فرز الكائنات


عند توصيل الأشياء بالأنابيب ، غالبًا ما يكون من الضروري فرزها. يتم تمرير أسماء الخصائص (مفاتيح الفرز) إلى أمر cmdlet لـ Sort-Object ، وتقوم بإرجاع الكائنات مرتبة حسب قيمها. يمكن فرز ناتج العمليات الجارية بسهولة حسب وقت المعالج (خاصية وحدة المعالجة المركزية):

Get-Process | Sort-Object –Property cpu

يمكن حذف المعلمة -Property عند استدعاء cmdlet لـ Sort-Object - يتم استخدامه افتراضيًا. للفرز العكسي ، استخدم المعلمة -Descending:

Get-Process | Sort-Object cpu -Descending



اختيار الأشياء وأجزائها


يسمح لك الأمر cmdlet Select-Object بتحديد عدد محدد من الكائنات في بداية أو نهاية خط الأنابيب باستخدام المعلمات -First أو -Last. باستخدامه ، يمكنك تحديد كائنات مفردة أو خصائص معينة ، بالإضافة إلى إنشاء كائنات جديدة على أساسها. سنحلل عمل cmdlet باستخدام أمثلة بسيطة.

يعرض الأمر التالي معلومات حول 10 عمليات تستهلك الحد الأقصى من ذاكرة الوصول العشوائي (خاصية WS):

Get-Process | Sort-Object WS -Descending | Select-Object -First 10



يمكنك تحديد خصائص معينة فقط للكائنات التي تمر عبر خط الأنابيب وإنشاء خصائص جديدة على أساسها:

Get-Process | Select-Object ProcessName, Id -First 1

نتيجة لخط الأنابيب ، سنحصل على كائن جديد ، يختلف هيكله عن الهيكل الذي تم إرجاعه بواسطة الأمر cmdlet Get-Process. سوف نتحقق من ذلك باستخدام Get-Member:

Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member



لاحظ أن Select-Object ترجع كائنًا واحدًا (-الأول 1) ، والذي يحتوي على حقلين فقط حددناهما: تم نسخ قيمهما من الكائن الأول الذي تم تمريره إلى خط الأنابيب باستخدام Get-Process cmdlet. باستخدام تحديد الكائن ، تستند إحدى طرق إنشاء كائنات في البرامج النصية PowerShell:

$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()



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

Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}



دعونا نلقي نظرة على هيكل الأجسام المارة عبر خط الأنابيب:

Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member



ForEach-Object و Group-Object و Measure-Object


هناك أوامر cmdlets أخرى للعمل مع الكائنات. على سبيل المثال ، سنتحدث عن الثلاثة الأكثر فائدة: يتيح لك

ForEach-Object تنفيذ كود PowerShell لكل كائن في خط الأنابيب:

ForEach-Object {   }

مجموعة الكائنات تجمع الكائنات حسب قيمة الخاصية:

Group-Object PropertyName

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

يقوم كائن القياس بتجميع معلمات التلخيص المتنوعة حسب قيم حقول الكائنات في خط الأنابيب (يحسب المجموع ويجد أيضًا القيمة الدنيا أو القصوى أو المتوسطة):

Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum

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

إنشاء كائنات .NET و COM (كائن جديد)


هناك العديد من مكونات البرامج مع واجهات .NET Core و COM مفيدة لمسؤولي النظام. باستخدام فئة System.Diagnostics.EventLog ، يمكنك إدارة سجلات النظام مباشرة من Windows PowerShell. دعونا نلقي نظرة على مثال لإنشاء مثيل من هذه الفئة باستخدام الأمر New-Object cmdlet مع المعلمة -TypeName:

New-Object -TypeName System.Diagnostics.EventLog



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

$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog



يرجى ملاحظة ما يلي: لقد حفظنا مخرجات الأمر في متغير $ AppLog. على الرغم من استخدام خطوط الأنابيب بشكل شائع في الوضع التفاعلي ، إلا أن البرمجة النصية غالبًا ما تتطلب الحفاظ على مرجع كائن. بالإضافة إلى ذلك ، يتم تضمين فئات .NET Core الرئيسية في مساحة اسم النظام: يبحث PowerShell بشكل افتراضي عن الأنواع المحددة فيه ، لذا فإن كتابة بيانات التشخيص بدلاً من System.Diagnostics.EventLog صحيحة تمامًا.

للعمل مع المجلة ، يمكنك الرجوع إلى الطرق المناسبة:

$AppLog | Get-Member -MemberType Method



لنفترض أنه تم مسحه باستخدام طريقة Clear () مع حقوق الوصول:

$AppLog.Clear()

يتم استخدام الأمر cmdlet New-Object للعمل مع مكونات COM. هناك الكثير منها - من المكتبات المزودة بخادم البرمجة النصية لـ Windows إلى تطبيقات ActiveX ، على سبيل المثال ، Internet Explorer. لإنشاء كائن COM ، يجب تحديد المعلمة -ComOject باستخدام معرف البرنامج ProgId للفئة المطلوبة:

New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject

لإنشاء كائناتك الخاصة بهيكل تعسفي ، فإن استخدام New-Object يبدو قديمًا ومرهقًا للغاية ؛ يتم استخدام cmdlet هذا للعمل مع مكونات البرامج الخارجية لـ PowerShell. في المقالات اللاحقة ، ستتم مناقشة هذه المسألة بمزيد من التفصيل. بالإضافة إلى كائنات .NET و COM ، سنتعرف أيضًا على كائنات CIM (WMI) و ADSI.

استدعاء الأساليب الثابتة


لا يمكن إنشاء مثيلات لبعض فئات .NET Core: تتضمن System.Environment و System.Math. فهي ثابتة وتحتوي فقط على خصائص وأساليب ثابتة. في الأساس ، هذه مكتبات مرجعية يتم استخدامها بدون إنشاء كائنات. يمكنك الرجوع إلى فئة ثابتة من خلال حرفي ، مع تضمين اسم النوع بين قوسين مربعين. علاوة على ذلك ، إذا نظرت إلى بنية الكائن باستخدام Get-Member ، فسترى النوع System.RuntimeType بدلاً من System.Environment:

[System.Environment] | Get-Member



لعرض العناصر الثابتة فقط ، تحتاج إلى استدعاء Get-Member باستخدام المعلمة -Static (انتبه إلى نوع الكائن):

[System.Environment] | Get-Member -Static



للوصول إلى الخصائص والأساليب الثابتة ، يتم استخدام نقطتين متتاليتين بدلاً من فترة بعد حرفية:

[System.Environment]::OSVersion

أو

$test=[System.Math]::Sqrt(25) 
$test
$test.GetType()



اكتب PSCustomObject


من بين العديد من أنواع البيانات المتاحة في PowerShell ، تجدر الإشارة إلى PSCustomObject ، المصمم لتخزين الكائنات ذات بنية عشوائية. يعتبر إنشاء مثل هذا الكائن باستخدام الأمر New-Object cmdlet طريقة كلاسيكية ، لكنها مرهقة ومتقادمة:

$object = New-Object  –TypeName PSCustomObject -Property @{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'}

دعونا نلقي نظرة على هيكل الكائن:

$object | Get-Member



بدءًا من PowerShell 3.0 ، تتوفر بنية أخرى:

$object = [PSCustomObject]@{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'
}

يمكنك الوصول إلى البيانات بإحدى الطرق المكافئة:

$object.Name

$object.'Name'

$value = 'Name'
$object.$value

فيما يلي مثال على تحويل جدول تجزئة موجود إلى كائن:

$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()



أحد عيوب الكائنات من هذا النوع هو أن ترتيب خصائصها يمكن أن يتغير. لتجنب ذلك ، يجب عليك استخدام السمة [مرتبة]:

$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko'; 
                                          City = 'Moscow';
                                          Country = 'Russia'
}

هناك خيارات أخرى لإنشاء كائن: أعلاه درسنا استخدام الأمر cmdlet لـ Select-Object . يبقى للتعامل مع إضافة وإزالة العناصر. للقيام بذلك للكائن من المثال السابق أمر بسيط للغاية:

$object | Add-Member –MemberType NoteProperty –Name Age  –Value 33
$object | Get-Member



يسمح لك الأمر cmdlet الخاص بـ Add-Member بإضافة خصائص ، ليس فقط ، ولكن أيضًا الأساليب إلى كائن $ $ الذي تم إنشاؤه سابقًا باستخدام بناء "-MemberType ScriptMethod":

$ScriptBlock = {
    #  
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member

ملاحظة: لتخزين الكود للطريقة الجديدة ، استخدمنا المتغير $ ScriptBlock من النوع ScriptBlock.



لإزالة الخصائص ، استخدم الطريقة المناسبة:

$object.psobject.properties.remove('Name')

إنشاء دروسك الخاصة


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

class MyClass
{
    #  
}

هذا هو نوع حقيقي من .NET Core ، يصف نصه خصائصه وأساليبه وعناصر أخرى. خذ بعين الاعتبار مثال تعريف فئة بسيطة:

class MyClass 
{
     [string]$Name
     [string]$City
     [string]$Country
}

لإنشاء كائن (مثيل لفئة) ، استخدم أمر cmdlet New-Object أو حرفية من نوع [MyClass] والطريقة الجديدة الكاذبة (المُنشئ الافتراضي):

$object = New-Object -TypeName MyClass

أو

$object = [MyClass]::new()

دعونا نحلل هيكل الكائن:

$object | Get-Member



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

بعد إنشاء الكائن ، قم بملء خصائصه:

$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object



لاحظ أنه في وصف الفئة ، لا يتم تعيين أنواع الخصائص فقط ، ولكن أيضًا قيمها الافتراضية:

class Example
{
     [string]$Name = 'John Doe'
}

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

class MyClass 
{
     [string]$Name
     [string]$City
     [string]$Country
     
     # 
     Smile([bool]$param1)
     {
         If($param1) {
            Write-Host ':)'
         }
     }
}

الآن يعرف ممثل صفنا كيف يبتسم:

$object = [MyClass]::new()
$object.Smile($true)

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

class MyClass2 : MyClass
{
      #  ,     MyClass
}
[MyClass2]::new().Smile($true)

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



1: Windows PowerShell
2: Windows PowerShell
3: ,


All Articles