Dalja tekstuale e komandave në dritaren e interpretuesit PowerShell është thjesht një mënyrë për të shfaqur informacionin në një format të kuptueshëm nga njeriu. Në të vërtetë, mjedisi në punën me objekte: komandlet dhe funksionet i pranojnë ata si input dhe , ndërsa tipet e variables të disponueshme në mënyrë interaktive dhe në skenare bazohen në klasat .NET. Në artikullin e katërt të ciklit, ne do të shqyrtojmë punën me objekte më në detaje.
Përmbajtja:
Objektet në PowerShell
KujtojmĂ« se objekti Ă«shtĂ« njĂ« grumbull fushash tĂ« dhĂ«nash (pronash, ngjarjesh etj.) dhe mĂ«nyrave pĂ«r pĂ«rpunimin e tyre (metodave). Struktura e tij pĂ«rcaktohet nga lloji, i cili zakonisht bazohet nĂ« klasat e pĂ«rdorura nĂ« platformĂ«n unike .NET Core. Gjithashtu ka mundĂ«si pĂ«r tĂ« punuar me objekte COM, CIM (WMI) dhe ADSI. Pronat dhe metodat janĂ« tĂ« nevojshme pĂ«r tĂ« kryer veprime tĂ« ndryshme mbi tĂ« dhĂ«nat; pĂ«r mĂ« tepĂ«r, nĂ« PowerShell, objektet mund tĂ« transmetohen si argumente nĂ« funksione dhe komandletĂ«, t'u jepen vlerat variablave, dhe gjithashtu ka (konvejeri ose pipeline). Ădo komandĂ« nĂ« konvejer i kalon daljet e saj sĂ« ardhshme njĂ«ra pas tjetrĂ«s â objekt pas objekti. PĂ«r pĂ«rpunim mund tĂ« pĂ«rdoren komandletĂ« e kompiluar ose tĂ« krijoni , pĂ«r tĂ« kryer manipulime tĂ« ndryshme me objektet nĂ« pipeline: filtrimi, renditja, grupimi dhe madje edhe ndryshimi i strukturĂ«s sĂ« tyre. Shkollimi i tĂ« dhĂ«nave nĂ« kĂ«tĂ« formĂ« ka njĂ« avantazh tĂ« madh: ekipi i marrjes nuk i duhet tĂ« merret me analizimin sintaksor tĂ« fluksit tĂ« bajtave (tekstit), tĂ« gjitha informacionet e nevojshme nxirren lehtĂ« pĂ«rmes qasjes nĂ« pronat dhe metodat pĂ«rkatĂ«se.
Shikimi i strukturës së objekteve
Si shembull, do të ekzekutojmë komandletin Get-Process, që lejon marrjen e informacionit rreth proceseve që po punojnë në sistem:

Ai do të nxjerrë në ekran disa të dhëna të formatizuara, të cilat nuk japin një pasqyrë të pronave të objekteve të kthyer dhe metodave të tyre. Për të bërë një analizë të hollësishme të rezultatit, duhet të mësojmë të studiojmë strukturën e objekteve dhe për këtë do të na ndihmojë komandleti Get-Member:
Get-Process | Get-Member 
Këtu tashmë shohim llojin dhe strukturën, dhe me ndihmën e parametrave shtesë mund të nxjerrim, për shembull, vetëm pronat e objektit që hyri:
Get-Process | Get-Member -MemberType PropertyKëto njohuri do të jenë të nevojshme për zgjidhjen e problemeve të administratës në mënyrë interaktive ose për të shkruar skriptet e tua: për shembull, për të marrë informacion mbi proceset që kanë ngecur në pronën e tyre "Responding".
Filtrimi i objekteve
PowerShell lejon kalimin e objekteve nëpër procesin e pipeline që i përmbushin një kusht të caktuar:
Where-Object { blloku i skriptit }Rezultati i ekzekutimit të bllokut të skriptit në kllapat duhet të jetë një vlerë logjike. Nëse ajo është e vërtetë ($true), objekti që hyri në komandën Where-Object do të kalojë më tej në pipeline, përndryshe (vlera $false) do të hiqet. Për shembull, le të nxjerrim listën e shërbimeve të ndaluara në Windows Server, domethënë atyre për të cilat pronësia Status ka vlerën "Stopped":
Get-Service | Where-Object {$_.Status -eq "Stopped"} 
Këtu ne shohim përsëri një paraqitje tekstuale, por nëse dëshiron të kuptosh llojin dhe strukturën e brendshme të objekteve që po kalojnë nëpër pipeline, nuk është e vështirë:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member 
Organizimi i objekteve
Gjatë procesit të përpunimit në vazhdimësi, shpesh kërkohet të bëhet renditja e objekteve. Komanda Sort-Object merr emrat e veçorive (çelësat e renditjes), dhe ajo kthen objekte të renditura sipas vlerave të tyre. Shfaqja e proceseve të ekzekutuar mund të renditet lehtësisht sipas kohës së procesorit të shpenzuar (veçoria cpu):
Get-Process | Sort-Object âProperty cpuParametri -Property nĂ« thirrjen e komandĂ«s Sort-Object mund tĂ« mos pĂ«rcaktohet â ai pĂ«rdoret si i paracaktuar. PĂ«r renditje nĂ« tĂ« kundĂ«rt pĂ«rdoret parametri -Descending:
Get-Process | Sort-Object cpu -Descending 
Shkëputja e objekteve dhe pjesëve të tyre
Komanda Select-Object lejon të shfaqim një numër të caktuar objektesh në fillim ose në fund të konveyorëve me anë të parametrave -First ose -Last. Me të mund të zgjidhen objekte të vetme ose veçori specifike, si dhe të krijohen objekte të reja mbi bazën e tyre. Le të shqyrtojmë punën e komandës me shembuj të thjeshtë.
Komanda në vazhdim tregon informacion për 10 proceset që konsumojnë sasinë maksimale të memories operative (veçoria WS):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10 
Mund të zgjidhni vetëm veçori të caktuara të objekteve që kalojnë përmes konveyorëve dhe të krijoni objekte të reja mbi bazën e tyre:
Get-Process | Select-Object ProcessName, Id -First 1Si pasojë e punës së konvejerit ne do të krijojmë një objekt të ri, struktura e të cilit do të diferojë nga struktura e kthyer nga komandleta Get-Process. Le të sigurohemi për këtë me Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member 
Vini re se Select-Object kthen një objekt të vetëm (-First 1), i cili ka vetëm dy fushat e specifikuara nga ne: vlerat e tyre ishin kopjuar nga objekti i parë i kaluar në konvejer nga komandleta Get-Process. Një nga mënyrat për të krijuar objekte në skenarët PowerShell bazohet në përdorimin e Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType() 
Me anĂ« tĂ« Select-Object mund tĂ« shtoni pronĂ«si tĂ« llogaritura objekteve, tĂ« cilat duhet tĂ« paraqiten nĂ« formĂ«n e . NĂ« kĂ«tĂ« rast, vlera e çelĂ«sit tĂ« parĂ« korrespondon me emrin e pronĂ«s, dhe vlera e dytĂ« â me vlerĂ«n e pronĂ«s pĂ«r elementin aktual tĂ« konvejerit:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} 
Le të shikojmë strukturën e objekteve që kalojnë përmes konvejerit:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member 
ForEach-Object, Group-Object dhe Measure-Object
Për të punuar me objektet, ekzistojnë edhe komandë të tjera. Si shembull, do të flasim për tri më të dobishmet:
ForEach-Object lejon të ekzekutoni kod në PowerShell për çdo objekt në pipeline:
ForEach-Object { blloku i skenarit }Group-Object grupizon objektet sipas vlerës së pronës:
Group-Object EmriPronësNëse e ekzekutoni me parametrin -NoElement, mund të merrni numrin e elementeve në grupe.
Measure-Object agregon parametra të ndryshëm përmbledhës sipas vlerave të fushave të objekteve në pipeline (llogarit shumën, gjithashtu gjen vlerën minimale, maksimale ose mesatare):
Measure-Object -Property EmriPronës -Minimum -Maximum -Average -SumZakonisht, komandët e trajtuara përdoren në modalitetin interaktiv, ndërsa në skripte shpesh krijohen me blloqe Begin, Process dhe End.
Krijimi i objekteve .NET dhe COM (New-Object)
EkzistojnĂ« shumĂ« komponente softuerike me ndĂ«rfaqe .NET Core dhe COM, tĂ« cilat janĂ« tĂ« dobishme pĂ«r administratoret e sistemeve. Me klasĂ«n System.Diagnostics.EventLog, mund tĂ« menaxhoni regjistrat sistemorĂ« drejtpĂ«rdrejt nga Windows PowerShell. Le tâi shqyrtojmĂ« shembujt e krijimit tĂ« njĂ« instancĂ« tĂ« kĂ«saj klase duke pĂ«rdorur komandĂ«n New-Object me parametrin -TypeName:
New-Object -TypeName System.Diagnostics.EventLog 
Pasi nuk kemi specificuar njĂ« regjistĂ«r tĂ« caktuar tĂ« ngjarjeve, instancat e marra tĂ« klasĂ«s nuk pĂ«rmbajnĂ« tĂ« dhĂ«na. PĂ«r ta ndryshuar kĂ«tĂ«, Ă«shtĂ« e nevojshme qĂ« gjatĂ« krijimit tĂ« tij tĂ« thĂ«rrasim njĂ« metodĂ« tĂ« veçantĂ« ndihmĂ«se me anĂ« tĂ« parametrave -ArgumentList. NĂ«se dĂ«shirojmĂ« tĂ« aksesojmĂ« regjistrin e aplikacionit, nĂ« konstruktori duhet tĂ« kalojmĂ« stringun âApplicationâ si argument:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog 
Kujdes: Ne e kemi ruajtur daljen e komandës në variablën $AppLog. Edhe pse në modin interaktiv zakonisht përdoren tubat, shkruajta të skriptit shpesh kërkon ruajtjen e një referencës ndaj objektit. Për më tepër, klasat kryesore .NET Core ndodhen në hapësirën e emrave System: PowerShell, nga burimi, kërkon automatikisht në të për llojet e specifikuara, kështu që shkruajta Diagnostics.EventLog në vend të System.Diagnostics.EventLog është krejtësisht e saktë.
Për të punuar me regjistrin, mund të përdorim metodat përkatëse:
$AppLog | Get-Member -MemberType Method 
Le të themi se ai pastrohet me metodën Clear() në rast se ka të drejta aksesimi:
$AppLog.Clear()Komanda New-Object pĂ«rdoret gjithashtu pĂ«r tĂ« punuar me komponentĂ«t COM. Ka shumĂ« prej tyre â nga skedarĂ«t e skenarĂ«ve tĂ« Windows qĂ« vijnĂ« me serverin deri te aplikacionet ActiveX, si, pĂ«r shembull, Internet Explorer. PĂ«r tĂ« krijuar njĂ« objekt COM, duhet tĂ« caktoni parametrin -ComObject me identifikuesin programor ProgId tĂ« klasĂ«s sĂ« kĂ«rkuar:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObjectPër të krijuar objekte të personalizuara me strukturë të rastësishme, përdorimi i New-Object duket shumë arkaik dhe i vështirë; ky komandlet përdoret për të punuar me komponentët e jashtëm në raport me PowerShell. Në artikujt në vazhdim, do të shqyrtojmë këtë çështje më në detaje. Përveç objekteve .NET dhe COM, ne gjithashtu do të studiojmë objektet CIM (WMI) dhe ADSI.
Thirrja e metodave statike
Instancat e disa klasave .NET Core nuk mund të krijohen: këtu përfshihen System.Environment dhe System.Math. Ato janë dhe përmbajnë vetëm vetitë dhe metodat statike. Në thelb, ato janë biblioteka referimi që përdoren pa krijuar objekte. Për të referuar një klasë statike, mund të përdorim një literal, duke e vendosur emrin e llojit në kllapa. Kur të shikojmë strukturën e objektit duke përdorur Get-Member, do të shohim llojin System.RuntimeType në vend të System.Environment:
[System.Environment] | Get-Member 
Për të parë vetëm elementet statike, duhet të thërrasim Get-Member me parametrin -Static (merrni parasysh llojin e objektit):
[System.Environment] | Get-Member -Static 
Për të aksesuar vetitë dhe metodat statike, përdoren dy dy pika radhazi në vend të pikës pas literalit:
[System.Environment]::OSVersionOse
$test=[System.Math]::Sqrt(25)
$test
$test.GetType() 
Lloji PSCustomObject
Një nga llojet e të dhënave që janë në disponibilitet në PowerShell është PSCustomObject, i cili është dizajnuar për të ruajtur objekte me strukturë të rastësishme. Krijimi i një objekti të tillë përmes komandës New-Object konsiderohet një mënyrë klasike, megjithatë është e rëndë dhe e vjetruar:
$object = New-Object âTypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
Le t'i hedhim një sy strukturës së objektit:
$object | Get-Member 
Nga PowerShell 3.0 është i disponueshëm edhe një sintaksë tjetër:
$object = [PSCustomObject]@{Emri = 'Ivan Danko';
Qyteti = 'Moskë';
Shteti = 'Rusia'
}
Këto të dhëna mund të aksesohen në një nga mënyrat ekuivalente:
$object.Emri
$object.'Emri'
$vlera = 'Emri'
$object.$vlera
Le të ilustrojmë një shembull të transformimit në një objekt nga një tabelë ekzistuese:
$hash = @{'Emri'='Ivan Danko'; 'Qyteti'='Moskë'; 'Shteti'='Rusia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()

Një nga disavantazhet e objekteve të këtij lloji është se rendi i pronave të tyre mund të ndryshojë. Për të shmangur këtë, është e nevojshme të përdoret atributi [ordered]:
$object = [PSCustomObject][ordered]@{Emri = 'Ivan Danko';
Qyteti = 'Moskë';
Shteti = 'Rusia'
}
Ka edhe mënyra të tjera për të krijuar objekte: më sipër ne shqyrtuam përdorimin e komandletit . Tani na mbetet të kuptojmë si të shtojmë dhe fshijmë elemente. Të bësh këtë për objektin nga shembulli i mëparshëm është mjaft e thjeshtë:
$object | Add-Member âMemberType NoteProperty âEmri Mosha âVlera 33
$object | Get-Member

Komandleti Add-Member lejon shtimin e jo vetëm pronave por edhe metodave për objektin e mëparshëm $object duke përdorur konstrukcionin "-MemberType ScriptMethod":
$ScriptBlock = {
# kod
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Ju lutemi vini re: për ruajtjen e kodit të metodës së re, ne përdorëm ndryshoren $ScriptBlock të tipit ScriptBlock.

Për të hequr pronat, përdoret metoda përkatëse:
$object.psobject.properties.remove('Name')
Krijimi i klasave tona
Në PowerShell 5.0, u shfaq mundësia për të përcaktuar duke përdorur sintaksën karakteristike të gjuhëve të programimit të orientuar ndaj objekteve. Për këtë, përdoret fjala kyçe Class, pas së cilës duhet të jepet emri i klasës dhe të përshkruhet trupi i saj në kllapa operative:
class MyClass
{
# trupi i klasës
}
Ky është një tip i vërtetë .NET Core, në trupin e të cilit përshkruhen pronat, metodat dhe elementët e tjerë. Le të shqyrtojmë një shembull të përcaktimit të një klase të thjeshtë:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Për të krijuar një objekt (instancë të klasës) përdoret komandleti , ose literal i tipit [MyClass] dhe new (konstruktori i parazgjedhur):
$object = New-Object -TypeName MyClassose
$object = [MyClass]::new()Le të analizojmë strukturën e objektit:
$object | Get-Member 
Mos u harroni për fushën e dukshmërisë: nuk mund të referoheni në emrin e tipit si një varg ose të përdorni literalin e tipit jashtë skenarit ose modulit ku është përcaktuar klasa. Megjithatë, funksionet mund të kthejnë instanca të klasës (objekte), të cilat do të jenë të disponueshme jashtë modulit ose skriptit.
Pas krijimit të një objekti, do të mbushim pronat e tij:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object

Vlen të theksohet se në përshkrimin e klasës përcaktohen jo vetëm tipet e pronave, por edhe vlerat e tyre të paracaktuara:
class Example
{
[string]$Name = 'John Doe'
}
Përshkrimi i metodës së klasës është i ngjashëm me përshkrimin e një funksioni, por pa përdorimin e fjalës kyçe function. Si në funksion, parametrat mund të kalohen në metoda kur është e nevojshme:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#përshkrimi i metodës
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Tani përfaqësuesi i klasës tonë di të buzëqeshë:
$object = [MyClass]::new()
$object.Smile($true)
Metodat mund tĂ« tejkalohen, pĂ«rveç kĂ«saj klasa ka , si klasat kanĂ« emra qĂ« pĂ«rputhen me emrin e klasĂ«s vetĂ«. NjĂ« klasĂ« e caktuar nĂ« skriptin ose modul PowerShell mund tĂ« shĂ«rbejĂ« si bazĂ« pĂ«r njĂ« tjetĂ«r â kĂ«shtu realizohet trashĂ«gimia. NĂ« kĂ«tĂ« rast, Ă«shtĂ« e lejuar pĂ«rdorimi i klasave ekzistuese .NET si baza.
class MyClass2 : MyClass
{
#trupi i klasës së re, e cila është bazë për MyClass
}
[MyClass2]::new().Smile($true)
Përshkrimi ynë i punës me objekte në PowerShell është i vështirë për t'u quajtur gjithëpërfshirës. Në publikimet e ardhshme do të përpiqemi ta thellojmë atë me shembuj praktikë: artikulli i pestë i ciklit do të përqendrohet në çështjet e integrimit të PowerShell me komponentet e jashtme të softuerit. Pjesët e kaluara mund të gjenden në lidhjet më poshtë.
Burimi: habr.com
