Тэкставая выснова каманд у акне інтэрпрэтатара PowerShell - усяго толькі спосаб адлюстравання інфармацыі ў прыдатным для чалавечага ўспрымання выглядзе. Насамрэч асяроддзе
змест:
Аб'екты ў PowerShell
Нагадаем, што аб'ект - гэта сукупнасць палёў дадзеных (уласцівасцяў, падзей і г.д.) і спосабаў іх апрацоўкі (метадаў). Яго структура задаецца тыпам, які як правіла грунтуецца на выкарыстоўвальных ва ўніфікаванай платформе. NET Core класах. Таксама ёсць магчымасць працаваць з аб'ектамі COM, CIM (WMI) і ADSI. Уласцівасці і метады патрэбныя для выканання розных дзеянняў над дадзенымі, акрамя таго ў PowerShell аб'екты можна перадаваць як аргументы ў функцыі і камандлеты, прысвойваць іх значэнні зменным, а таксама існуе
Прагляд структуры аб'ектаў
Для прыкладу запусцім камандлет Get-Process, які дазваляе атрымаць інфармацыю аб працавальных у сістэме працэсах:
Ён выведзе на экран некаторыя адфарматаваныя тэкставыя дадзеныя, якія не даюць уяўленні пра ўласцівасці якія вяртаюцца аб'ектаў і іх метадах. Для тонкага прэпаравання высновы неабходна навучыцца даследаваць структуру аб'ектаў і ў гэтым нам дапаможа камандлет Get-Member:
Get-Process | Get-Member
Тут мы ўжо бачым тып і структуру, а з дапамогай дадатковых параметраў можам, напрыклад, вывесці толькі ўласцівасці які трапіў на ўваход аб'екта:
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"}
Тут мы зноў бачым тэкставае паданне, але пры жаданні зразумець тып і ўнутраная прылада праходзілых праз канвеер аб'ектаў няцяжка:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
Сартаванне аб'ектаў
Пры канвеернай апрацоўцы аб'ектаў часта ўзнікае неабходнасць іх сартавання. У камандлет Sort-Object перадаюцца імёны ўласцівасцяў (ключоў сартавання), а ён вяртае спарадкаваныя па іх значэннях аб'екты. Выснова запушчаных працэсаў нескладана адсартаваць па затрачаным працэсарным часе (уласцівасць cpu):
Get-Process | Sort-Object –Property cpu
Параметр -Property пры выкліку камандлета Sort-Object можна не паказваць - ён выкарыстоўваецца па змаўчанні. Для зваротнага сартавання ўжываецца параметр -Descending:
Get-Process | Sort-Object cpu -Descending
Вылучэнне аб'ектаў і іх частак
Камандлет Select-Object дазваляе вылучыць пэўную колькасць аб'ектаў у пачатку ці ў канцы канвеера з дапамогай параметраў -First ці -Last. З яго дапамогай можна абраць адзінкавыя аб'екты ці вызначаныя ўласцівасці, а таксама стварыць на іх аснове новыя аб'екты. Разбяром працу камандлета на простых прыкладах.
Наступная каманда выводзіць інфармацыю аб 10 працэсах, якія спажываюць максімальны аб'ём аператыўнай памяці (уласцівасць WS):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
Можна вылучыць толькі вызначаныя ўласцівасці праходзілых праз канвеер аб'ектаў і стварыць на іх аснове новыя:
Get-Process | Select-Object ProcessName, Id -First 1
У выніку працы канвеера мы атрымаем новы аб'ект, структура якога будзе адрознівацца ад структуры якія вяртаюцца камандлетам Get-Process. Пераканаемся ў гэтым пры дапамозе Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member
Звярніце ўвагу, што Select-Object вяртае адзінкавы аб'ект (-First 1), у якога ўсяго два паказаныя намі палі: іх значэння былі скапіяваныя з першага перададзенага ў канвеер камандлетам Get-Process аб'екта. На выкарыстанні Select-Object заснаваны адзін са спосабаў стварэння аб'ектаў у сцэнарах 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
Для працы з аб'ектамі існуюць і іншыя камандлеты. Для прыкладу раскажам пра тры найбольш карысныя:
Для кожнага аб'екта дазваляе выканаць код на мове PowerShell для кожнага аб'екта ў канвееры:
ForEach-Object { блок сценария }
Group-Object групуе аб'екты па значэнні ўласцівасці:
Group-Object PropertyName
Калі запусціць яго з параметрам -NoElement, можна пазнаць колькасць элементаў у групах.
Мера-аб'ект агрэгуе розныя зводныя параметры па значэннях палёў аб'ектаў у канвееры (вылічае суму, а таксама знаходзіць мінімальнае, максімальнае або сярэдняе значэнне):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
Звычайна разгледжаныя камандлеты выкарыстоўваюцца ў інтэрактыўным рэжыме, а ў скрыптах часцей ствараюцца
Стварэнне аб'ектаў. NET і COM (New-Object)
Ёсць мноства праграмных кампанентаў з інтэрфейсамі. NET Core і COM, якія спатрэбяцца сістэмным адміністратарам. З дапамогай класа System.Diagnostics.EventLog можна кіраваць сістэмнымі часопісамі непасрэдна з Windows PowerShell. Разбяром прыклад стварэння асобніка гэтага класа пры дапамозе камандлета New-Object з параметрам -TypeName:
New-Object -TypeName System.Diagnostics.EventLog
Паколькі мы не пазначылі пэўны часопіс падзей, атрыманы экзэмпляр класа не ўтрымлівае даных. Каб гэта змяніць, неабходна падчас яго стварэння выклікаць адмысловы метад-канструктар пры дапамозе параметра -ArgumentList. Калі мы жадаем атрымаць доступ да часопіса прыкладанняў, у канструктар варта перадаць радок "Application" у якасці аргументу:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
Звярніце ўвагу: выходныя дадзеныя каманды мы захавалі ў зменнай $AppLog. Хаця ў інтэрактыўным рэжыме звычайна выкарыстоўваюцца канвееры, напісанне сцэнарыяў часта патрабуе захавання спасылкі на аб'ект. Акрамя таго асноўныя класы. NET Core змяшчаюцца ў прасторы імёнаў System: PowerShell па змаўчанні шукае ў ім паказаныя тыпы, таму напісанне Diagnostics.EventLog замест System.Diagnostics.EventLog суцэль карэктна.
Для працы з часопісам можна звяртацца да адпаведных метадаў:
$AppLog | Get-Member -MemberType Method
Скажам чысціцца ён метадам Clear() пры наяўнасці правоў доступу:
$AppLog.Clear()
Камандлет New-Object ужываецца і для працы з САМ-кампанентамі. Іх даволі шмат - ад пастаўляюцца з серверам сцэнарыяў Windows бібліятэк да прыкладанняў ActiveX, такіх, напрыклад, як Internet Explorer. Каб стварыць САМ-аб'ект, патрабуецца задаць параметр -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. Яны з'яўляюцца
[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 лічыцца класічным, але грувасткім і састарэлым спосабам:
$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()
Адзін з недахопаў аб'ектаў гэтага тыпу - парадак іх уласцівасцяў можа памяняцца. Каб гэтага пазбегнуць, неабходна выкарыстоўваць атрыбут [ordered]:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Ёсць і іншыя варыянты стварэння аб'екта: вышэй мы разгледзелі выкарыстанне камандлета
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
Камандлет Add-Member дазваляе дадаваць раней створанаму аб'екту $object не толькі ўласцівасці, але і метады пасродкам выкарыстання канструкцыі "-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 MyClass
{
# тело класса
}
Гэта сапраўдны тып. NET Core, у целе якога апісваюцца яго ўласцівасці, метады і іншыя элементы. Разгледзім прыклад вызначэння найпрасцейшага класа:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Для стварэння аб'екта (экзэмпляра класа) выкарыстоўваецца камандлет
$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'
}
Апісанне метаду класа нагадвае апісанне функцыі, але без выкарыстання службовага слова function. Як і ў функцыі, у метады пры неабходнасці перадаюцца параметры:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Цяпер прадстаўнік нашага класа ўмее ўсміхацца:
$object = [MyClass]::new()
$object.Smile($true)
Метады можна перагружаць, акрамя таго ў класа бываюць
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
Наша апісанне працы з аб'ектамі ў PowerShell цяжка назваць вычарпальным. У наступных публікацыях паспрабуем яго паглыбіць на практычных прыкладах: пяты артыкул цыклу будзе прысвечаны пытанням інтэграцыі PowerShell са іншымі праграмнымі кампанентамі. Мінулыя часткі можна знайсці па спасылках ніжэй.
Крыніца: habr.com