Textutdata frÄn PowerShell-tolkfönstret Àr helt enkelt ett sÀtt att visa information pÄ ett sÀtt som Àr begripligt för mÀnniskor. Faktum Àr att miljön Àr avsedd för arbete med objekt: cmdlets och funktioner tar emot dem som indata och , med tillgÀngliga datatyper i interaktivt lÀge och i skript baserade pÄ .NET-klasser. I den fjÀrde artikeln i serien ska vi undersöka hur man arbetar med objekt mer i detalj.
InnehÄll:
Objekt i PowerShell
Vi pĂ„minner om att ett objekt Ă€r en samling av datavaror (egenskaper, hĂ€ndelser och sĂ„ vidare) och metoder för att bearbeta dem. Dess struktur bestĂ€ms av en typ som vanligtvis baseras pĂ„ klasser frĂ„n den enhetliga plattformen .NET Core. Det finns ocksĂ„ möjlighet att arbeta med COM-, CIM (WMI) och ADSI-objekt. Egenskaper och metoder behövs för att utföra olika operationer pĂ„ data, dessutom kan objekt i PowerShell överföras som argument till funktioner och cmdlets, tilldelas vĂ€rden till variabler, och det finns ocksĂ„ (pipeline). Varje kommando i pipelinen överför sin utdata till nĂ€sta i följd â objekt för objekt. För bearbetning kan komplicerade cmdlets anvĂ€ndas eller egna , för att utföra olika manipulationer med objekt i pipelinen: filtrering, sortering, gruppering och till och med Ă€ndra deras struktur. Ăverföring av data pĂ„ detta sĂ€tt har en stor fördel: den mottagande kommandot behöver inte hantera analysen av byteflödet (texten), all nödvĂ€ndig information kan enkelt extraheras genom att referera till motsvarande egenskaper och metoder.
Visning av objektstrukturer
Som exempel kör vi cmdlet: Get-Process, vilket gör det möjligt att hÀmta information om de processer som körs i systemet:

Den kommer att skriva ut viss formaterad textinformation pÄ skÀrmen, som inte ger nÄgon insikt om egenskaperna hos de ÄterlÀmnade objekten och deras metoder. För att noggrant analysera outputen mÄste vi lÀra oss att undersöka objektets struktur, och detta hjÀlper oss med cmdlet Get-Member:
Get-Process | Get-Member 
HÀr ser vi redan typ och struktur, och med hjÀlp av ytterligare parametrar kan vi till exempel visa endast egenskaperna för det objekt som har kommit in:
Get-Process | Get-Member -MemberType PropertyDenna kunskap kommer att vara anvÀndbar för att lösa administreringsuppgifter i interaktivt lÀge eller för att skriva egna skript: lÄt oss sÀga att vi vill fÄ information om hÀngande processer baserat pÄ egenskapen Responding.
Filtrera objekt
PowerShell tillÄter att passera objekt genom röret som uppfyller ett visst villkor:
Where-Object { skriptblock }Resultatet av körningen av skriptblocket inom klamrarna mÄste vara ett logiskt vÀrde. Om det Àr sant ($true) kommer det objekt som passerar till Where-Object-kommandot att vidarebefordras i röret, annars (vÀrde $false) kommer det att tas bort. Som exempel visar vi en lista över stoppade Windows Server-tjÀnster, det vill sÀga sÄdana med egenskapen Status som har vÀrdet "Stopped":
Get-Service | Where-Object {$_.Status -eq "Stopped"} 
HÀr ser vi Äterigen en textuell representation, men om man vill förstÄ typen och den inre strukturen hos objekten som passerar genom röret Àr det inte svÄrt:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member 
Sortera objekt
Vid rörbehandling av objekt uppstÄr ofta behovet av sortering. Till Sort-Object-kommandot skickas namnen pÄ egenskaperna (sorteringsnycklarna), och det returnerar objekt som har ordnats efter deras vÀrden. Det Àr enkelt att sortera utdata över aktiva processer efter den processor som anvÀnts (egenskapen cpu):
Get-Process | Sort-Object âProperty cpuParametern -Property vid anrop av Sort-Object-kommandot behöver inte anges â den anvĂ€nds som standard. För omvĂ€nd sortering anvĂ€nds parametern -Descending:
Get-Process | Sort-Object cpu -Descending 
Extrahera objekt och deras delar
Kommandot Select-Object tillÄter att vÀlja ett visst antal objekt i början eller slutet av röret med hjÀlp av parametrarna -First eller -Last. Med det kan man vÀlja enstaka objekt eller specifika egenskaper, samt skapa nya objekt baserat pÄ dem. LÄt oss gÄ igenom kommandots arbete med enkla exempel.
Följande kommando visar information om 10 processer som anvÀnder mest RAM (egenskapen WS):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10 
Man kan framhÀva endast specifika egenskaper hos objekten som passerar genom röret och skapa nya baserat pÄ dem:
Get-Process | Select-Object ProcessName, Id -First 1Genom att köra pipelinen fÄr vi ett nytt objekt vars struktur kommer att skilja sig frÄn den som returneras av kommandot Get-Process. LÄt oss bekrÀfta detta med Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member 
Observera att Select-Object returnerar ett enstaka objekt (-First 1) som endast har de tvÄ fÀlten vi angav: deras vÀrden kopierades frÄn det första objektet som skickades till pipelinen av kommandot Get-Process. En av metoderna för att skapa objekt i PowerShell-skript baseras pÄ anvÀndningen av Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType() 
Med Select-Object kan man lÀgga till berÀknade egenskaper till objekten som ska presenteras i form av . HÀr motsvarar vÀrdet av den första nyckeln namnet pÄ egenskapen, och vÀrdet av den andra nyckeln Àr vÀrdet av egenskapen för det aktuella objektet i pipelinen:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} 
LÄt oss titta pÄ strukturen hos objekten som passerar genom pipelinen:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member 
ForEach-Object, Group-Object och Measure-Object
Det finns Àven andra kommandon för att arbeta med objekt. Som exempel kan vi nÀmna tre av de mest anvÀndbara:
ForEach-Object möjliggör att köra kod i PowerShell för varje objekt i pipelinen:
ForEach-Object { skriptblock }Group-Object grupperar objekt efter vÀrdet av en egenskap:
Group-Object PropertyNameOm man kör det med parametern -NoElement kan man fÄ antalet element i grupperna.
Measure-Object aggregerar olika sammanfattningar baserat pÄ vÀrdena av objektsfÀlt i pipelinen (berÀknar summan samt hittar minimala, maximala eller genomsnittliga vÀrden):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -SumDe behandlade kommandona anvÀnds vanligtvis i interaktivt lÀge, medan skript oftare skapas med blocken Begin, Process och End.
Skapa .NET- och COM-objekt (New-Object)
Det finns mÄnga programkomponenter med .NET Core och COM-grÀnssnitt som Àr anvÀndbara för systemadministratörer. Med klassen System.Diagnostics.EventLog kan man hantera systemloggar direkt frÄn Windows PowerShell. LÄt oss gÄ igenom ett exempel pÄ hur man skapar en instans av denna klass med kommandot New-Object och parametern -TypeName:
New-Object -TypeName System.Diagnostics.EventLog 
Eftersom vi inte angav en specifik hÀndelselogg innehÄller den erhÄllna klassinstansen inga data. För att Àndra detta mÄste vi vid skapandet kalla pÄ en speciell konstruktör med hjÀlp av parametern -ArgumentList. Om vi vill fÄ tillgÄng till applikationsloggen bör vi skicka strÀngen "Application" som argument till konstruktorn:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog 
Observera: utdata frĂ„n kommandot har sparats i variabeln $AppLog. Ăven om rörledningar vanligtvis anvĂ€nds i interaktivt lĂ€ge krĂ€ver skriptskrivning ofta att man sparar en referens till objektet. Dessutom finns de grundlĂ€ggande .NET Core-klasserna i namnomrĂ„det System: PowerShell letar som standard i detta namnomrĂ„de efter angivna typer, sĂ„ att skriva Diagnostics.EventLog istĂ€llet för System.Diagnostics.EventLog Ă€r helt korrekt.
För att arbeta med loggen kan vi anvÀnda motsvarande metoder:
$AppLog | Get-Member -MemberType Method 
LÄt oss sÀga att den rensas med metoden Clear() om behörighet finns:
$AppLog.Clear()Cmdlet New-Object anvĂ€nds ocksĂ„ för att arbeta med COM-komponenter. Det finns ganska mĂ„nga av dem â frĂ„n de som följer med serverns Windows-skriptbibliotek till ActiveX-applikationer, som exempelvis Internet Explorer. För att skapa ett COM-objekt mĂ„ste parametern -ComObject anges med ProgId för den önskade klassen:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObjectFör att skapa egna objekt med godtycklig struktur verkar anvÀndningen av New-Object förÄldrad och omstÀndig, denna cmdlet anvÀnds för att arbeta med externa programkomponenter i förhÄllande till PowerShell. I kommande artiklar kommer denna frÄga att behandlas mer i detalj. Utöver .NET- och COM-objekt kommer vi ocksÄ att studera CIM-objekt (WMI) och ADSI.
Anropa statiska metoder
Instanser av vissa .NET Core-klasser kan inte skapas: bland dem finns System.Environment och System.Math. De Àr och innehÄller endast statiska egenskaper och metoder. I praktiken Àr detta referensbibliotek som anvÀnds utan att skapa objekt. Man kan referera till en statisk klass genom att skriva typnamnet inom hakparenteser. NÀr man tittar pÄ objektets struktur med hjÀlp av Get-Member kommer vi att se typen System.RuntimeType istÀllet för System.Environment:
[System.Environment] | Get-Member 
För att visa endast statiska element mÄste du anropa Get-Member med parametern -Static (observera objektets typ):
[System.Environment] | Get-Member -Static 
För att fÄ Ätkomst till statiska egenskaper och metoder anvÀnds tvÄ pÄ varandra följande kolon istÀllet för punkt efter litteralen:
[System.Environment]::OSVersionEller
$test=[System.Math]::Sqrt(25)
$test
$test.GetType() 
Typen PSCustomObject
Bland de mÄnga tillgÀngliga datatyperna i PowerShell Àr PSCustomObject vÀrt att nÀmna, som Àr avsedd för att lagra objekt med godtycklig struktur. Att skapa ett sÄdant objekt med hjÀlp av cmdleten New-Object anses vara ett klassiskt men klumpigt och förÄldrat sÀtt:
$object = New-Object âTypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
LÄt oss titta pÄ objektets struktur:
$object | Get-Member 
FrÄn och med PowerShell 3.0 Àr en annan syntax ocksÄ tillgÀnglig:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Du kan fÄ Ätkomst till data pÄ ett av de likvÀrdiga sÀtten:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
LÄt oss ge ett exempel pÄ konvertering av en befintlig hash-tabell till ett objekt:
$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()

En av nackdelarna med objekt av denna typ Àr att ordningen pÄ deras egenskaper kan Àndras. För att undvika detta mÄste du anvÀnda attributet [ordered]:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Det finns Àven andra alternativ för att skapa ett objekt: ovan har vi sett anvÀndningen av cmdleten . Vi mÄste göra klart för att lÀgga till och ta bort element. Det Àr ganska enkelt för objektet frÄn det tidigare exemplet:
$object | Add-Member âMemberType NoteProperty âName Age âValue 33
$object | Get-Member

Cmdleten Add-Member gör det möjligt att lÀgga till inte bara egenskaper till det tidigare skapade objektet $object, men Àven metoder med hjÀlp av konstruktionen "-MemberType ScriptMethod":
$ScriptBlock = {
# kod
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Observera: för att lagra koden för den nya metoden tog vi variabeln $ScriptBlock av typen ScriptBlock.

För att ta bort egenskaper anvÀnds motsvarande metod:
$object.psobject.properties.remove('Name')
Skapa egna klasser
I PowerShell 5.0 introducerades möjligheten att definiera med den syntax som Àr karakteristisk för objektorienterade programmeringssprÄk. För detta anvÀnds nyckelordet Class, följt av klassens namn och dess kropp som beskrivs inom klamrar:
class MyClass
{
# klassens kropp
}
Detta Àr en riktig typ i .NET Core, vars kropp beskriver dess egenskaper, metoder och andra element. LÄt oss titta pÄ ett exempel pÄ definitionen av en enkel klass:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
För att skapa ett objekt (instans av klassen) anvÀnds cmdlet , eller litteralen [MyClass] och new (standardkonstruktör):
$object = New-Object -TypeName MyClasseller
$object = [MyClass]::new()LÄt oss analysera objektets struktur:
$object | Get-Member 
Det Àr viktigt att komma ihÄg om synlighet: man kan inte referera till typnamnet som en strÀng eller anvÀnda typens litteral utanför skriptet eller modulen dÀr klassen definieras. Funktioner kan dock returnera instanser av klassen (objekt) som kommer att vara tillgÀngliga utanför modulen eller skriptet.
Efter att ha skapat objektet ska vi fylla i dess egenskaper:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object

Vi noterar att i klassbeskrivningen anges inte bara egenskapernas typer utan Àven deras standardvÀrden:
class Example
{
[string]$Name = 'John Doe'
}
Beskrivningen av klassmetoden liknar beskrivningen av en funktion, men utan att anvÀnda nyckelordet function. Precis som i funktionen kan parametrar skickas till metoderna vid behov:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#beskrivning av metoden
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Nu kan vÄr klassrepresentation le ett leende:
$object = [MyClass]::new()
$object.Smile($true)
Metoder kan överlagras, dessutom kan klassen ha , samt konstruktörer vars namn matchar klassens namn. En klass som definieras i ett PowerShell-skript eller modul kan fungera som bas för en annan klass â sĂ„ realiseras arv. Befintliga .NET-klasser kan anvĂ€ndas som bas:
class MyClass2 : MyClass
{
# kroppen av den nya klassen, dÀr MyClass Àr basen
}
[MyClass2]::new().Smile($true)
VÄr beskrivning av arbete med objekt i PowerShell kan knappast kallas uttömmande. I kommande inlÀgg kommer vi att fördjupa det med praktiska exempel: den femte artikeln i serien kommer att handla om frÄgorna kring integration av PowerShell med tredjepartsprogram. Tidigare delar kan hittas via lÀnkarna nedan.
KĂ€lla: habr.com
