Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Текстовият изход на командите в прозореца на PowerShell е просто начин за представяне на информация в разбираем за човека формат. Всъщност средата е насочена за работа с обекти: командлетите и функциите получават обектите на вход и върщат ги на изхода, а наличните в интерактивния режим и в скриптовете типове променливи се основават на класовете на .NET. В четвърта статия от цикъла ще разгледаме работата с обектите по-подробно.

Съдържание:

Обекти в PowerShell
Преглед на структурата на обектите
Филтриране на обекти
Сортиране на обекти
Извличане на обекти и техните части
ForEach-Object, Group-Object и Measure-Object
Създаване на обекти .NET и COM (New-Object)
Извикване на статични методи
Тип PSCustomObject
Създаване на собствени класове

Обекти в PowerShell

Напомняме, че обектът е съвкупност от полета данни (свойства, събития и т.н.) и начини за обработка (методи). Неговата структура се определя от типа, който обикновено се основава на класовете в унифицираната платформа .NET Core. Има също така възможност за работа с COM, CIM (WMI) и ADSI обекти. Свойствата и методите са нужни за извършване на различни действия с данните, освен това в PowerShell обектите могат да се предават като аргументи на функции и командлети, да се присвояват на променливи, а също така съществува механизъм за композиране на команди (конвейер или pipeline). Всяка команда в конвейера предава своя изход на следващата последователно — обект по обект. За обработка могат да се използват предварително компилирани командлети или да се създадат собствени разширени функции, за да извършват различни манипулации с обектите в конвейера: филтриране, сортиране, групиране и дори промяна на структурата им. Предаването на данни по този начин има сериозно предимство: командата получаваща данни не трябва да обработва потока от байтове (текст), цялата необходима информация лесно се извлича чрез достъп до съответните свойства и методи.

Преглед на структурата на обектите

Например, ще стартираме командлет Get-Process, който позволява да получим информация за активните в системата процеси:

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Той ще изведе на екрана определени форматирани текстови данни, които не дават представа за свойствата на върнатите обекти и техните методи. За финото проучване на извода е необходимо да научим как да изследваме структурата на обектите и в това ще ни помогне командлет Get-Member:

Get-Process | Get-Member

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Тук вече виждаме типа и структурата, а с помощта на допълнителни параметри можем, например, да извлечем само свойствата на обекта, който е входящ.

Get-Process | Get-Member -MemberType Property

Тези знания ще са необходими за решаване на административни задачи в интерактивен режим или за писане на собствени скриптове: да речем, за да получим информация за забавени процеси по свойството Responding.

Филтриране на обекти

PowerShell позволява преминаването на обекти по конвейера, които отговарят на определено условие:

Where-Object { блок сценария }

Резултатът от изпълнението на блока в операторните скоби трябва да бъде логическа стойност. Ако е вярна ($true), входящият обект в командлета Where-Object ще бъде предаден по конвейера, в противен случай (стойността $false) той ще бъде премахнат. За пример, нека изведем списък на спрените услуги на Windows Server, т.е. тези, чиято собственост Status има стойност „Stopped“:

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Тук отново виждаме текстово представяне, но при желание да разберем типа и вътрешната структура на обектите, преминаващи през конвейера, не е трудно:

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Сортиране на обекти

При обработка на обекти по конвейера често възниква необходимост от тяхното сортиране. В командлета Sort-Object се подават имена на свойства (ключове за сортиране), а той връща подредени по техните стойности обекти. Изходът на активните процеси не е труден за сортиране по изразходвано процесорно време (свойство cpu):

Get-Process | Sort-Object –Property cpu

Параметърът -Property при извикване на командлета Sort-Object не е необходимо да се посочва — той се използва по подразбиране. За обратно сортиране се използва параметърът -Descending:

Get-Process | Sort-Object cpu -Descending

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Извличане на обекти и техните части

Командлетът Select-Object позволява да се извлекат определен брой обекти в началото или края на конвейера с помощта на параметрите -First или -Last. С него можем да изберем единични обекти или определени свойства, както и да създадем нови обекти на тяхна основа. Нека разгледаме работата на командлета с прости примери.

Следващата команда показва информация за 10 процеса, консумиращи максимален обем оперативна памет (свойство WS):

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Можем да изберем само определени свойства на преминаващите през конвейера обекти и да създадем нови на тяхна основа:

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

В резултат на работата на конвейера получаваме нов обект, структурата на който ще се различава от структурата, възвръщана от командлета Get-Process. Нека се уверим в това с Get-Member:

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Обърнете внимание, че Select-Object връща единичен обект (-First 1), който има само два зададени от нас полета: техните стойности са копирани от първия предаден в конвейера обект чрез командлета Get-Process. На използването на Select-Object се основава един от начините за създаване на обекти в сценарии на PowerShell:

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

С помощта на Select-Object можете да добавите на обектите пресметнати свойства, които да бъдат представени под формата на хеш-таблица. В същото време стойността на първия ключ съответства на името на свойството, а стойността на втория — на стойността на свойството за текущия елемент на конвейера:

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Нека погледнем структурата на обектите, преминаващи през конвейера:

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

ForEach-Object, Group-Object и Measure-Object

За работа с обектите съществуват и други командлети. За примера ще споменем три от най-полезните:

ForEach-Object позволява да изпълнявате код на PowerShell за всеки обект в конвейера:

ForEach-Object { блок на сценария }

Group-Object групира обектите по стойност на свойството:

Group-Object PropertyName

Ако го стартирате с параметъра -NoElement, можете да разберете броя на елементите в групите.

Measure-Object агрегира различни обобщаващи параметри по стойностите на полетата на обектите в конвейера (изчислява сумата, както и намира минималната, максималната или средната стойност):

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

Обикновено разгледаните командлети се използват в интерактивен режим, докато в скриптовете най-често се създават функции с блокове Begin, Process и End.

Създаване на обекти .NET и COM (New-Object)

Съществуват множество софтуерни компоненти с интерфейси .NET Core и COM, които ще бъдат полезни за системните администратори. С помощта на класа System.Diagnostics.EventLog можете да управлявате системните журнали директно от Windows PowerShell. Нека разгледаме пример за създаване на екземпляр от този клас чрез командлета New-Object с параметъра -TypeName:

New-Object -TypeName System.Diagnostics.EventLog

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Тъй като не указахме определен журнал за събития, полученият екземпляр на класа не съдържа данни. За да променим това, е необходимо при създаването му да се извика специален метод-конструктор с параметъра -ArgumentList. Ако искаме да получим достъп до журнала на приложенията, в конструктора трябва да предадем низ „Application“ като аргумент:

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Обърнете внимание: изходните данни от командата запазихме в променливата $AppLog. Въпреки че в интерактивен режим обикновено се използват конвейери, писането на скриптове често изисква запазване на справка към обекта. Освен това основните класове .NET Core се съдържат в пространството от имена System: PowerShell по подразбиране търси в него посочените типове, така че написването на Diagnostics.EventLog вместо System.Diagnostics.EventLog е напълно коректно.

За работа с журнала може да се обърнете към съответните методи:

$AppLog | Get-Member -MemberType Method

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Нека кажем, че той се изтрива чрез метода Clear() при наличие на права за достъп:

$AppLog.Clear()

Командлетът New-Object се прилага и за работа с COM компоненти. Техният брой е значителен - от доставените с Windows Server библиотеки до приложения ActiveX, като например Internet Explorer. За да създадете COM обект, трябва да зададете параметъра -ComObject с програмния идентификатор ProgId на необходимия клас:

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

За създаването на собствени обекти с произволна структура, използването на New-Object изглежда твърде архаично и обемисто, този командлет се използва за работа с външни по отношение на PowerShell програмни компоненти. В следващите статии този въпрос ще бъде разгледан по-подробно. Освен обекти .NET и COM ще изучим и обекти CIM (WMI) и ADSI.

Извикване на статични методи

Екземплярите на някои класове .NET Core не могат да бъдат създавани: сред тях са System.Environment и System.Math. Те са статични и съдържат само статични свойства и методи. Всъщност това са справочни библиотеки, които се използват без създаване на обекти. За да се позовете на статичен клас, можете да използвате литерал, като заключите името на типа в квадратни скоби. При това, ако погледнете структурата на обекта чрез Get-Member, ще видите тип System.RuntimeType вместо System.Environment:

[System.Environment] | Get-Member

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

За да видите само статични елементи, трябва да извикате Get-Member с параметър -Static (обърнете внимание на типа на обекта):

[System.Environment] | Get-Member -Static

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

За достъп до статични свойства и методи се използват две последователни двоеточия вместо точка след литерала:

[System.Environment]::OSVersion

Или

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Тип PSCustomObject

Сред многото налични в PowerShell типове данни, PSCustomObject за съхранение на обекти с произволна структура заслужава специално споменаване. Създаването на такъв обект с помощта на командлета New-Object се счита за класически, но тромав и остарял метод:

$object = New-Object  –TypeName PSCustomObject -Property @{Name = 'Иван Данков'; 
                                          City = 'Москва';
                                          Country = 'Русия'}

Нека да погледнем структурата на обекта:

$object | Get-Member

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Започвайки от PowerShell 3.0, е наличен и друг синтаксис:

$object = [PSCustomObject]@{Name = 'Иван Данков'; 
                                          City = 'Москва';
                                          Country = 'Русия'
}

Доступът до данните може да се осъществи по един от следните еквивалентни начини:

$object.Name

$object.'Name'

$value = 'Name'
$object.$value

Ще дам пример за преобразуване в обект на съществуваща хеш таблица:

$hash = @{'Name'='Иван Данков'; 'City'='Москва'; 'Country'='Русия'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Един от недостатъците на обектите от този тип е, че редът на свойствата им може да се промени. За да се избегне това, е необходимо да се използва атрибутът [ordered]:

$object = [PSCustomObject][ordered]@{Name = 'Иван Данков'; 
                                          City = 'Москва';
                                          Country = 'Русия'
}

Има и други варианти за създаване на обект: по-горе разгледахме използването на командлета Select-Object. Остава да разберем как да добавим и премахнем елементи. Да го направим за обекта от предишния пример е доста просто:

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

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Командлетът Add-Member позволява добавянето на не само свойства, но и методи на вече съществуващия обект $object чрез конструкцията "-MemberType ScriptMethod":

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

Обърнете внимание: за съхранение на кода на новия метод използвахме променливата $ScriptBlock от тип ScriptBlock.

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

За премахване на свойства се използва съответния метод:

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

Създаване на собствени класове

В PowerShell 5.0 се появи възможност за определяне на класове с използване на синтаксиса, характерен за обектно-ориентираните програмни езици. За това служебната дума Class е предназначена, след която трябва да зададете името на класа и да опишете неговото тяло в фигурни скоби:

class MyClass
{
    # тяло на класа
}

Това е действителен тип .NET Core, в тялото на който се описват неговите свойства, методи и други елементи. Нека разгледаме примера за дефиниция на най-простия клас:

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

За създаване на обект (екземпляр на класа) се използва командлетът New-Object, или литералът на типа [MyClass] и псевдостатичния метод new (конструктор по подразбиране):

$object = New-Object -TypeName MyClass

или

$object = [MyClass]::new()

Нека анализираме структурата на обекта:

$object | Get-Member

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Не трябва да забравяме за областта на видимост: не може да се прави справка към името на типа като низ или да се използва литералът на типа извън скрипта или модула, в който е дефиниран класът. В същото време функциите могат да връщат екземпляри на класа (обекти), които ще бъдат достъпни извън модула или скрипта.

След създаването на обекта, нека запълним неговите свойства:

$object.Name = 'Иван Данков'
$object.City = 'Москва'
$object.Country = 'Русия'
$object

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Забележете, че в описанието на класа се задават не само типовете свойства, но и техните стойности по подразбиране:

class Example
{
     [string]$Name = 'Джон До'
}

Описанието на метода на класа наподобява описанието на функция, но без използването на служебната дума function. Както и в функцията, в методите при необходимост се предават параметри:

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: Предаване на параметри в скриптове и функции, създаване на командлети

Какво е Windows PowerShell и как се използва? Част 4: Работа с обекти, собствени класове

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster