Textutmatningen av kommandon i PowerShell-tolkfönstret är bara ett sätt att visa information i en form som lämpar sig för mänsklig uppfattning. Onsdag faktiskt
Innehållsförteckning:
Objekt i PowerShell
Låt oss komma ihåg att ett objekt är en samling datafält (egenskaper, händelser, etc.) och metoder för att bearbeta dem (metoder). Dess struktur specificeras av en typ, som vanligtvis är baserad på klasser som används i den förenade .NET Core-plattformen. Det är även möjligt att arbeta med COM, CIM (WMI) och ADSI-objekt. Egenskaper och metoder behövs för att utföra olika åtgärder på data; dessutom, i PowerShell, kan objekt skickas som argument till funktioner och cmdlets, tilldelas deras värden till variabler, och det finns också
Titta på strukturen av objekt
Låt oss till exempel köra Get-Process cmdleten, som låter dig få information om processerna som körs i systemet:
Det kommer att visa en del formaterad textdata som inte ger någon uppfattning om egenskaperna hos de returnerade objekten och deras metoder. För att finjustera utdata måste vi lära oss hur man undersöker strukturen på objekt, och Get-Member cmdleten hjälper oss med detta:
Get-Process | Get-Member
Här ser vi redan typ och struktur, och med hjälp av ytterligare parametrar kan vi till exempel endast visa egenskaperna för objektet som ingår i inmatningen:
Get-Process | Get-Member -MemberType Property
Denna kunskap kommer att behövas för att lösa administrationsproblem interaktivt eller för att skriva dina egna skript: till exempel för att få information om hängda processer med hjälp av egenskapen Responding.
Filtrera objekt
PowerShell tillåter att objekt som uppfyller ett visst villkor passeras genom en pipeline:
Where-Object { блок сценария }
Resultatet av att köra skriptblocket inom parentes måste vara ett booleskt värde. Om det är sant ($true), kommer objektet som matas in i Where-Object-cmdleten att skickas längs pipelinen, annars ($false) kommer det att tas bort. Låt oss till exempel visa en lista över stoppade Windows Server-tjänster, dvs. de vars Status-egenskap är inställd på "Stoppad":
Get-Service | Where-Object {$_.Status -eq "Stopped"}
Även här ser vi en textrepresentation, men om du vill förstå typen och den inre strukturen hos objekten som passerar genom pipelinen är det inte svårt:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
Sortering av objekt
Vid rörledningsbehandling av objekt finns det ofta ett behov av att sortera dem. Sort-Object-cmdleten skickas vidare namnen på egenskaper (sorteringsnycklar) och returnerar objekt ordnade efter deras värden. Det är lätt att sortera utdata från pågående processer efter CPU-tid (cpu-egenskap):
Get-Process | Sort-Object –Property cpu
Parametern -Property kan utelämnas när du anropar cmdleten Sort-Object, den används som standard. För omvänd sortering, använd parametern -Descending:
Get-Process | Sort-Object cpu -Descending
Välja objekt och deras delar
Select-Object-cmdleten låter dig välja ett specifikt antal objekt i början eller slutet av en pipeline med hjälp av parametrarna -First eller -Last. Med dess hjälp kan du välja enstaka objekt eller vissa egenskaper, och även skapa nya objekt baserat på dem. Låt oss titta på hur cmdleten fungerar med enkla exempel.
Följande kommando visar information om de 10 processerna som förbrukar den maximala mängden RAM (WS-egenskap):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
Du kan bara välja vissa egenskaper för objekt som passerar genom pipelinen och skapa nya baserat på dem:
Get-Process | Select-Object ProcessName, Id -First 1
Som ett resultat av pipelinens drift kommer vi att få ett nytt objekt, vars struktur kommer att skilja sig från strukturen som returneras av Get-Process cmdleten. Låt oss verifiera 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 bara har två av fälten vi angav: deras värden kopierades från det första objektet som skickades in i pipelinen av Get-Process cmdleten. Ett av sätten att skapa objekt i PowerShell-skript är baserat på att använda Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()
Med Select-Object kan du lägga till beräknade egenskaper till objekt som måste representeras som
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}
Låt oss titta på strukturen av föremål som passerar genom transportören:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member
För varje-objekt, grupp-objekt och mått-objekt
Det finns andra cmdlets för att arbeta med objekt. Som ett exempel, låt oss prata om de tre mest användbara:
För varje objekt låter dig köra PowerShell-kod för varje objekt i pipelinen:
ForEach-Object { блок сценария }
Grupp-objekt grupperar objekt efter egenskapsvärde:
Group-Object PropertyName
Om du kör det med parametern -NoElement kan du ta reda på antalet element i grupperna.
Mått-Objekt aggregerar olika sammanfattningsparametrar efter objektfältsvärden i pipeline (beräknar summan och hittar även minimi-, max- eller medelvärde):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
Vanligtvis används de diskuterade cmdletarna interaktivt och skapas ofta i skript.
Skapa .NET- och COM-objekt (New-Object)
Det finns många programvarukomponenter med .NET Core- och COM-gränssnitt som är användbara för systemadministratörer. Med klassen System.Diagnostics.EventLog kan du hantera systemloggar direkt från Windows PowerShell. Låt oss titta på ett exempel på att skapa en instans av den här klassen med hjälp av New-Object-cmdleten med parametern -TypeName:
New-Object -TypeName System.Diagnostics.EventLog
Eftersom vi inte angav en specifik händelselogg, innehåller den resulterande instansen av klassen inga data. För att ändra detta måste du anropa en speciell konstruktormetod när den skapas med parametern -ArgumentList. Om vi vill komma åt applikationsloggen bör vi skicka strängen "Application" som ett argument till konstruktorn:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
Observera att vi sparade utdata från kommandot i variabeln $AppLog. Även om pipelines ofta används i interaktivt läge, kräver skrivning av skript ofta att en referens till ett objekt bibehålls. Dessutom finns kärnklasserna .NET Core i systemnamnutrymmet: PowerShell söker som standard efter specificerade typer i det, så att skriva Diagnostics.EventLog istället för System.Diagnostics.EventLog är helt korrekt.
För att arbeta med loggen kan du använda lämpliga metoder:
$AppLog | Get-Member -MemberType Method
Låt oss säga att det rensas med metoden Clear() om det finns åtkomsträttigheter:
$AppLog.Clear()
New-Object-cmdleten används också för att arbeta med COM-komponenter. Det finns ganska många av dem - från biblioteken som levereras med Windows-skriptservern till ActiveX-applikationer, som Internet Explorer. För att skapa ett COM-objekt måste du ställa in parametern -ComObject med den programmatiska ProgId för önskad klass:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
För att skapa dina egna objekt med en godtycklig struktur, ser användningen av New-Object för ålderdomlig och besvärlig ut; denna cmdlet används för att arbeta med programvarukomponenter utanför PowerShell. I framtida artiklar kommer denna fråga att diskuteras mer i detalj. Förutom .NET- och COM-objekt kommer vi även att utforska CIM (WMI) och ADSI-objekt.
Anropa statiska metoder
Vissa .NET Core-klasser kan inte instansieras, inklusive System.Environment och System.Math. Dom är
[System.Environment] | Get-Member
För att endast visa statiska medlemmar, ring Get-Member med parametern -Static (observera objekttypen):
[System.Environment] | Get-Member -Static
För att komma åt statiska egenskaper och metoder, använd två på varandra följande kolon istället för en punkt efter bokstaven:
[System.Environment]::OSVersion
Eller
$test=[System.Math]::Sqrt(25)
$test
$test.GetType()
Skriv PSCustomObject
Bland de många datatyperna som finns tillgängliga i PowerShell är det värt att nämna PSCustomObject, designat för att lagra objekt med en godtycklig struktur. Att skapa ett sådant objekt med hjälp av New-Object-cmdleten anses vara ett klassiskt, men besvärligt 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 finns en annan syntax tillgänglig:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Du kan komma åt data på ett av motsvarande sätt:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
Här är ett exempel på att konvertera en befintlig hashtabell 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 andra alternativ för att skapa ett objekt: ovan tittade vi på att använda cmdleten
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
Add-Member cmdleten låter dig lägga till inte bara egenskaper utan även metoder till ett tidigare skapat $objekt genom att använda "-MemberType ScriptMethod"-konstruktionen:
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Observera att vi använde variabeln $ScriptBlock av typen ScriptBlock för att lagra koden för den nya metoden.
För att ta bort egenskaper, använd motsvarande metod:
$object.psobject.properties.remove('Name')
Skapa dina egna klasser
PowerShell 5.0 introducerade möjligheten att definiera
class MyClass
{
# тело класса
}
Detta är en äkta .NET Core-typ, med en kropp som beskriver dess egenskaper, metoder och andra element. Låt oss titta på ett exempel på att definiera den enklaste klassen:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
För att skapa ett objekt (klassinstans), använd cmdleten
$object = New-Object -TypeName MyClass
eller
$object = [MyClass]::new()
Låt oss analysera objektets struktur:
$object | Get-Member
Glöm inte omfattning: du kan inte hänvisa till ett typnamn som en sträng eller använda en bokstavlig typ utanför skriptet eller modulen där klassen är definierad. I det här fallet kan funktioner returnera klassinstanser (objekt) som kommer att vara tillgängliga utanför modulen eller skriptet.
När du har skapat objektet, fyll i dess egenskaper:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object
Observera att klassbeskrivningen inte bara anger egenskapstyperna utan även deras standardvärden:
class Example
{
[string]$Name = 'John Doe'
}
Beskrivningen av en klassmetod liknar beskrivningen av en funktion, men utan att använda funktionsordet. Som i en funktion skickas parametrar till metoder om det behövs:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Nu kan representanten för vår klass le:
$object = [MyClass]::new()
$object.Smile($true)
Metoder kan överbelastas, dessutom har en klass
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
Vår beskrivning av att arbeta med objekt i PowerShell är knappast uttömmande. I följande publikationer kommer vi att försöka fördjupa det med praktiska exempel: den femte artikeln i serien kommer att ägnas åt frågorna om att integrera PowerShell med programvarukomponenter från tredje part. Tidigare delar kan hittas på länkarna nedan.
Källa: will.com