Tekstualni izlaz naredbi u prozoru tumača PowerShell je samo način da se informacije prikažu u obliku prikladnom za ljudsku percepciju. Zapravo u srijedu za rad s objektima: cmdleti i funkcije ih primaju kao ulaz i , a tipovi varijabli dostupni interaktivno iu skriptama su zasnovani na .NET klasama. U četvrtom članku serije detaljnije ćemo proučiti rad s objektima.
Sadržaj:
Objekti u PowerShell-u
Podsjetimo da je objekt skup polja podataka (osobina, događaja, itd.) i metoda za njihovu obradu (metoda). Njegova struktura je određena tipom, koji se obično zasniva na klasama koje se koriste u objedinjenoj .NET Core platformi. Također je moguć rad sa COM, CIM (WMI) i ADSI objektima. Svojstva i metode su potrebne za izvođenje različitih radnji nad podacima; osim toga, u PowerShell-u objekti se mogu proslijediti kao argumenti funkcijama i cmdletima, dodijeliti njihove vrijednosti varijablama, a postoji i (transporter ili cjevovod). Svaka naredba u cjevovodu prosljeđuje svoj izlaz na sljedeću redom, objekt po objekt. Za obradu možete koristiti kompajlirane cmdletove ili kreirati vlastite za obavljanje raznih manipulacija sa objektima u procesu: filtriranje, sortiranje, grupisanje, pa čak i promjena njihove strukture. Prenos podataka u ovom obliku ima ozbiljnu prednost: tim koji prima ne mora da analizira tok bajtova (tekst), sve potrebne informacije se lako dohvate pozivanjem odgovarajućih svojstava i metoda.
Pregled strukture objekata
Na primjer, pokrenimo Get-Process cmdlet, koji vam omogućava da dobijete informacije o procesima koji se pokreću u sistemu:

Prikazaće neke formatirane tekstualne podatke koji ne daju nikakvu ideju o svojstvima vraćenih objekata i njihovih metoda. Da bismo fino podesili izlaz, moramo naučiti kako ispitati strukturu objekata, a Get-Member cmdlet će nam pomoći u tome:
Get-Process | Get-Member 
Ovdje već vidimo tip i strukturu, a uz pomoć dodatnih parametara možemo, na primjer, prikazati samo svojstva objekta uključenog u ulaz:
Get-Process | Get-Member -MemberType PropertyOvo znanje će biti potrebno za interaktivno rješavanje problema administracije ili za pisanje vlastitih skripti: na primjer, za dobivanje informacija o obješenim procesima koristeći svojstvo Responding.
Filtriranje objekata
PowerShell dozvoljava da objekti koji ispunjavaju određeni uslov prođu kroz cjevovod:
Where-Object { блок сценария }Rezultat izvršavanja bloka skripte unutar zagrada operatora mora biti logička vrijednost. Ako je vrijednost true ($true), objekat proslijeđen cmdletu Where-Object bit će proslijeđen niz cjevovod; u suprotnom (vrijednost $false), bit će izbrisan. Na primjer, prikažimo listu zaustavljenih servisa. Windows Server, tj. oni čije svojstvo Status ima vrijednost „Zaustavljeno“:
Get-Service | Where-Object {$_.Status -eq "Stopped"} 
Ovdje ponovo vidimo tekstualni prikaz, ali ako želite razumjeti tip i unutrašnju strukturu objekata koji prolaze kroz cjevovod, to nije teško:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member 
Sortiranje objekata
Prilikom cjevovodne obrade objekata, često postoji potreba za njihovim sortiranjem. Komandi Sort-Object se prosljeđuju imena svojstava (ključevi za sortiranje) i vraća objekte poredane prema njihovim vrijednostima. Lako je sortirati izlaz pokrenutih procesa prema utrošenom CPU vremenu (svojstvo procesora):
Get-Process | Sort-Object –Property cpuParametar -Property se može izostaviti kada se poziva Sort-Object cmdlet; koristi se po defaultu. Za obrnuto sortiranje, koristite parametar -Descending:
Get-Process | Sort-Object cpu -Descending 
Odabir predmeta i njihovih dijelova
cmdlet Select-Object omogućava vam da odaberete određeni broj objekata na početku ili kraju cjevovoda pomoću parametara -First ili -Last. Uz njegovu pomoć, možete odabrati pojedinačne objekte ili određena svojstva, a također kreirati nove objekte na temelju njih. Pogledajmo kako cmdlet radi na jednostavnim primjerima.
Sljedeća naredba prikazuje informacije o 10 procesa koji troše maksimalnu količinu RAM-a (WS svojstvo):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10 
Možete odabrati samo određena svojstva objekata koji prolaze kroz cjevovod i kreirati nova na osnovu njih:
Get-Process | Select-Object ProcessName, Id -First 1Kao rezultat rada cevovoda, dobićemo novi objekat čija će se struktura razlikovati od strukture koju vraća Get-Process cmdlet. Potvrdimo ovo koristeći Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member 
Imajte na umu da Select-Object vraća jedan objekat (-First 1) koji ima samo dva polja koja smo naveli: njihove vrijednosti su kopirane iz prvog objekta koji je u cjevovod proslijeđen cmdlet Get-Process. Jedan od načina za kreiranje objekata u PowerShell skriptama temelji se na korištenju Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType() 
Koristeći Select-Object, možete dodati izračunata svojstva objektima koji trebaju biti predstavljeni kao . U ovom slučaju, vrijednost njegovog prvog ključa odgovara imenu svojstva, a vrijednost drugog ključa odgovara vrijednosti svojstva za trenutni element cjevovoda:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} 
Pogledajmo strukturu objekata koji prolaze kroz transporter:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member 
ForEach-Object, Group-Object i Measure-Object
Postoje i druge cmdlet komande za rad sa objektima. Kao primjer, razgovarajmo o tri najkorisnija:
ForEach-Object omogućava vam da pokrenete PowerShell kod za svaki objekat u cjevovodu:
ForEach-Object { блок сценария }Grupa-Objekat grupira objekte po vrijednosti svojstva:
Group-Object PropertyNameAko ga pokrenete s parametrom -NoElement, možete saznati broj elemenata u grupama.
Mjera-Objekat agregira različite zbirne parametre prema vrijednostima polja objekta u cjevovodu (izračunava zbroj, a također pronalazi minimalnu, maksimalnu ili prosječnu vrijednost):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -SumTipično, cmdleti o kojima se govori koriste se interaktivno i često se kreiraju u skriptama. sa blokovima Početak, Proces i Kraj.
Kreiranje .NET i COM objekata (New-Object)
Postoje mnoge softverske komponente sa .NET Core i COM interfejsima koje su korisne za sistem administratore. Korištenjem klase System.Diagnostics.EventLog, možete upravljati sistemskim logovima direktno iz Windows PowerShell. Pogledajmo primjer kreiranja instance ove klase korištenjem cmdleta New-Object s parametrom -TypeName:
New-Object -TypeName System.Diagnostics.EventLog 
Pošto nismo naveli određeni dnevnik događaja, rezultirajuća instanca klase ne sadrži podatke. Da biste to promijenili, morate pozvati poseban konstruktorski metod tokom njegovog kreiranja koristeći parametar -ArgumentList. Ako želimo pristupiti dnevniku aplikacije, trebali bismo proslediti niz "Application" kao argument konstruktoru:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog 
Imajte na umu da smo sačuvali izlaz naredbe u varijablu $AppLog. Iako se cjevovodi obično koriste u interaktivnom načinu rada, pisanje skripti često zahtijeva održavanje reference na objekt. Osim toga, osnovne .NET Core klase su sadržane u System imenskom prostoru: PowerShell po defaultu traži određene tipove u njemu, tako da je pisanje Diagnostics.EventLog umjesto System.Diagnostics.EventLog sasvim ispravno.
Za rad s dnevnikom možete koristiti odgovarajuće metode:
$AppLog | Get-Member -MemberType Method 
Recimo da je obrisano metodom Clear() ako postoje prava pristupa:
$AppLog.Clear()Cmdlet New-Object se također koristi za rad s COM komponentama. Ima ih popriličan broj, iz skripti koje se isporučuju sa serverom. Windows biblioteke za ActiveX aplikacije, kao što je Internet Explorer. Da biste kreirali COM objekt, potrebno je da navedete parametar -ComObject sa ProgId-om željene klase:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObjectZa kreiranje vlastitih objekata sa proizvoljnom strukturom, korištenje New-Object izgleda previše arhaično i glomazno; ovaj cmdlet se koristi za rad sa softverskim komponentama izvan PowerShell-a. U budućim člancima o ovom pitanju će se detaljnije govoriti. Osim .NET i COM objekata, istražit ćemo i CIM (WMI) i ADSI objekte.
Pozivanje statičkih metoda
Neke .NET Core klase se ne mogu instancirati, uključujući System.Environment i System.Math. Oni su i sadrže samo statička svojstva i metode. Ovo su u suštini referentne biblioteke koje se koriste bez kreiranja objekata. Možete upućivati na statičku klasu kroz literal tako što ćete naziv tipa staviti u uglaste zagrade. Međutim, ako pogledamo strukturu objekta koristeći Get-Member, vidjet ćemo tip System.RuntimeType umjesto System.Environment:
[System.Environment] | Get-Member 
Da vidite samo statične članove, pozovite Get-Member sa parametrom -Static (obratite pažnju na tip objekta):
[System.Environment] | Get-Member -Static 
Za pristup statičkim svojstvima i metodama, koristite dvije uzastopne dvotočke umjesto tačke nakon literala:
[System.Environment]::OSVersionOr
$test=[System.Math]::Sqrt(25)
$test
$test.GetType() 
Upišite PSCustomObject
Među brojnim tipovima podataka dostupnim u PowerShell-u, vrijedi spomenuti PSCustomObject, dizajniran za pohranjivanje objekata proizvoljne strukture. Kreiranje takvog objekta pomoću cmdleta New-Object smatra se klasičnim, ali nezgrapnim i zastarjelim načinom:
$object = New-Object –TypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
Pogledajmo strukturu objekta:
$object | Get-Member 
Počevši od PowerShell-a 3.0, dostupna je još jedna sintaksa:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Podacima možete pristupiti na jedan od ekvivalentnih načina:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
Evo primjera pretvaranja postojeće hashtable u objekt:
$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()

Jedan od nedostataka objekata ovog tipa je to što se redoslijed njihovih svojstava može mijenjati. Da biste to izbjegli, morate koristiti atribut [ordered]:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Postoje i druge opcije za kreiranje objekta: gore smo pogledali korištenje cmdleta . Ostaje samo da smislite dodavanje i uklanjanje elemenata. Uraditi ovo za objekt iz prethodnog primjera je prilično jednostavno:
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member

Add-Member cmdlet vam omogućava da dodate ne samo svojstva, već i metode prethodno kreiranom $objektu koristeći konstrukciju "-MemberType ScriptMethod":
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Imajte na umu da smo koristili varijablu $ScriptBlock tipa ScriptBlock da pohranimo kod za novi metod.

Da biste uklonili svojstva, koristite odgovarajuću metodu:
$object.psobject.properties.remove('Name')
Kreiranje vlastitih klasa
PowerShell 5.0 uveo je mogućnost definiranja koristeći sintaksnu karakteristiku objektno orijentisanih programskih jezika. Za to je namijenjena servisna riječ Class, nakon čega treba navesti ime klase i opisati njeno tijelo u operatorskim zagradama:
class MyClass
{
# тело класса
}
Ovo je pravi .NET Core tip, sa tijelom koje opisuje njegova svojstva, metode i druge elemente. Pogledajmo primjer definiranja najjednostavnije klase:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Za kreiranje objekta (instance klase), koristite cmdlet , ili literal tipa [MyClass] i novi (podrazumevani konstruktor):
$object = New-Object -TypeName MyClassili
$object = [MyClass]::new()Analizirajmo strukturu objekta:
$object | Get-Member 
Ne zaboravite na opseg: ne možete se odnositi na ime tipa kao string ili koristiti literal tipa izvan skripte ili modula u kojem je klasa definirana. U ovom slučaju, funkcije mogu vratiti instance klase (objekte) koji će biti dostupni izvan modula ili skripte.
Nakon kreiranja objekta, popunite njegova svojstva:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object

Imajte na umu da opis klase specificira ne samo tipove svojstava, već i njihove zadane vrijednosti:
class Example
{
[string]$Name = 'John Doe'
}
Opis metode klase liči na opis funkcije, ali bez upotrebe riječi funkcije. Kao iu funkciji, parametri se prosljeđuju metodama ako je potrebno:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Sada se predstavnik našeg razreda može nasmiješiti:
$object = [MyClass]::new()
$object.Smile($true)
Metode mogu biti preopterećene; pored toga, klasa ima , kao i konstruktori čija se imena poklapaju sa imenom same klase. Klasa definirana u skripti ili PowerShell modulu može poslužiti kao osnova za drugu - ovako se implementira nasljeđivanje. U ovom slučaju je dozvoljeno koristiti postojeće .NET klase kao osnovne:
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
Naš opis rada sa objektima u PowerShell-u teško da je iscrpan. U sljedećim publikacijama pokušat ćemo ga produbiti praktičnim primjerima: peti članak u nizu će biti posvećen pitanjima integracije PowerShell-a sa softverskim komponentama treće strane. Ranije dijelove možete pronaći na linkovima ispod.
izvor: www.habr.com
