Textový výstup příkazů v okně interpretu PowerShellu je jen způsob, jak zobrazit informace ve formě vhodné pro lidské vnímání. Vlastně středa
Obsah:
Objekty v PowerShellu
Připomeňme, že objekt je soubor datových polí (vlastností, událostí atd.) a metod pro jejich zpracování (metody). Jeho struktura je specifikována typem, který obvykle vychází z tříd používaných v jednotné platformě .NET Core. Dále je možné pracovat s objekty COM, CIM (WMI) a ADSI. Vlastnosti a metody jsou potřeba k provádění různých akcí s daty, v PowerShellu lze navíc objekty předávat jako argumenty funkcím a rutinám, přiřazovat jejich hodnoty proměnným a také
Zobrazení struktury objektů
Spusťte například rutinu Get-Process, která vám umožní získat informace o procesech běžících v systému:
Zobrazí některá formátovaná textová data, která nedávají žádnou představu o vlastnostech vrácených objektů a jejich metodách. Pro doladění výstupu se musíme naučit zkoumat strukturu objektů a pomůže nám s tím rutina Get-Member:
Get-Process | Get-Member
Zde již vidíme typ a strukturu a pomocí dalších parametrů můžeme například zobrazit pouze vlastnosti objektu zahrnutého ve vstupu:
Get-Process | Get-Member -MemberType Property
Tyto znalosti budou potřeba pro interaktivní řešení administračních problémů nebo pro psaní vlastních skriptů: například pro získání informací o zavěšených procesech pomocí vlastnosti Responding.
Filtrování objektů
PowerShell umožňuje, aby objekty, které splňují určitou podmínku, byly předány potrubím:
Where-Object { блок сценария }
Výsledkem provedení bloku skriptu v závorkách musí být booleovská hodnota. Pokud je to pravda ($true), objekt, který je vložen do rutiny Where-Object, bude předán potrubím, jinak ($false) bude odstraněn. Zobrazme si například seznam zastavených služeb Windows Serveru, tzn. ty, jejichž vlastnost Status je nastavena na „Zastaveno“:
Get-Service | Where-Object {$_.Status -eq "Stopped"}
Zde opět vidíme textovou reprezentaci, ale pokud chcete pochopit typ a vnitřní strukturu objektů procházejících potrubím, není to obtížné:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
Třídění objektů
Při potrubním zpracování objektů je často potřeba je třídit. Rutina Sort-Object předá názvy vlastností (třídicí klíče) a vrátí objekty seřazené podle jejich hodnot. Je snadné seřadit výstup běžících procesů podle stráveného času CPU (vlastnost CPU):
Get-Process | Sort-Object –Property cpu
Parametr -Property lze při volání rutiny Sort-Object vynechat; používá se ve výchozím nastavení. Pro obrácené řazení použijte parametr -Descending:
Get-Process | Sort-Object cpu -Descending
Výběr objektů a jejich částí
Rutina Select-Object umožňuje vybrat konkrétní počet objektů na začátku nebo na konci kanálu pomocí parametrů -First nebo -Last. S jeho pomocí můžete vybrat jednotlivé objekty nebo určité vlastnosti a také na jejich základě vytvořit nové objekty. Podívejme se, jak rutina funguje na jednoduchých příkladech.
Následující příkaz zobrazí informace o 10 procesech spotřebovávajících maximální množství paměti RAM (vlastnost WS):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
Můžete vybrat pouze určité vlastnosti objektů procházejících potrubím a na jejich základě vytvořit nové:
Get-Process | Select-Object ProcessName, Id -First 1
V důsledku provozu pipeline obdržíme nový objekt, jehož struktura se bude lišit od struktury vrácené rutinou Get-Process. Pojďme si to ověřit pomocí Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member
Všimněte si, že Select-Object vrací jeden objekt (-First 1), který má pouze dvě z námi zadaných polí: jejich hodnoty byly zkopírovány z prvního objektu předaného do kanálu rutinou Get-Process. Jeden ze způsobů, jak vytvořit objekty ve skriptech PowerShellu, je založen na použití Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()
Pomocí Select-Object můžete přidat vypočítané vlastnosti k objektům, které je třeba reprezentovat jako
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}
Podívejme se na strukturu předmětů procházejících dopravníkem:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member
ForEach-Object, Group-Object a Measure-Object
Pro práci s objekty existují další rutiny. Promluvme si například o třech nejužitečnějších:
Pro každý objekt umožňuje spouštět kód PowerShellu pro každý objekt v kanálu:
ForEach-Object { блок сценария }
Skupina-Objekt seskupuje objekty podle hodnoty vlastnosti:
Group-Object PropertyName
Pokud jej spustíte s parametrem -NoElement, můžete zjistit počet prvků ve skupinách.
Měřit-objekt agreguje různé souhrnné parametry podle hodnot polí objektu v kanálu (vypočítá součet a také najde minimální, maximální nebo průměrnou hodnotu):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
Obvykle se diskutované rutiny používají interaktivně a často se vytvářejí ve skriptech.
Vytváření objektů .NET a COM (New-Object)
Existuje mnoho softwarových komponent s rozhraními .NET Core a COM, které jsou užitečné pro systémové administrátory. Pomocí třídy System.Diagnostics.EventLog můžete spravovat systémové protokoly přímo z prostředí Windows PowerShell. Podívejme se na příklad vytvoření instance této třídy pomocí rutiny New-Object s parametrem -TypeName:
New-Object -TypeName System.Diagnostics.EventLog
Protože jsme nezadali konkrétní protokol událostí, výsledná instance třídy neobsahuje žádná data. Chcete-li to změnit, musíte během vytváření zavolat speciální metodu konstruktoru pomocí parametru -ArgumentList. Pokud chceme získat přístup k protokolu aplikace, měli bychom konstruktoru předat řetězec "Application" jako argument:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
Upozorňujeme, že výstup příkazu jsme uložili do proměnné $AppLog. Ačkoli se kanály běžně používají v interaktivním režimu, psaní skriptů často vyžaduje udržování odkazu na objekt. Kromě toho jsou základní třídy .NET Core obsaženy v oboru názvů System: PowerShell v něm standardně hledá zadané typy, takže zápis Diagnostics.EventLog místo System.Diagnostics.EventLog je zcela správný.
Chcete-li pracovat s protokolem, můžete použít příslušné metody:
$AppLog | Get-Member -MemberType Method
Řekněme, že je vymazán metodou Clear(), pokud existují přístupová práva:
$AppLog.Clear()
Rutina New-Object se také používá pro práci s komponentami COM. Je jich poměrně hodně – od knihoven dodávaných se skriptovacím serverem Windows až po aplikace ActiveX, jako je Internet Explorer. Chcete-li vytvořit objekt COM, musíte nastavit parametr -ComObject s programovým ProgId požadované třídy:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
Chcete-li vytvořit vlastní objekty s libovolnou strukturou, vypadá použití New-Object příliš archaicky a těžkopádně; tato rutina se používá pro práci se softwarovými komponentami mimo PowerShell. V dalších článcích bude tato problematika rozebrána podrobněji. Kromě objektů .NET a COM prozkoumáme také objekty CIM (WMI) a ADSI.
Volání statických metod
Některé třídy .NET Core nelze vytvořit, včetně System.Environment a System.Math. Oni jsou
[System.Environment] | Get-Member
Chcete-li zobrazit pouze statické členy, zavolejte Get-Member s parametrem -Static (všimněte si typu objektu):
[System.Environment] | Get-Member -Static
Chcete-li získat přístup ke statickým vlastnostem a metodám, použijte místo tečky za literálem dvě po sobě jdoucí dvojtečky:
[System.Environment]::OSVersion
Nebo
$test=[System.Math]::Sqrt(25)
$test
$test.GetType()
Zadejte PSCustomObject
Mezi četnými datovými typy dostupnými v PowerShellu stojí za zmínku PSCustomObject, určený pro ukládání objektů s libovolnou strukturou. Vytvoření takového objektu pomocí rutiny New-Object je považováno za klasický, ale těžkopádný a zastaralý způsob:
$object = New-Object –TypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
Podívejme se na strukturu objektu:
$object | Get-Member
Počínaje PowerShell 3.0 je k dispozici další syntaxe:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
K datům můžete přistupovat jedním z ekvivalentních způsobů:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
Zde je příklad převodu existující hashtable na objekt:
$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()
Jednou z nevýhod objektů tohoto typu je, že se může měnit pořadí jejich vlastností. Abyste tomu zabránili, musíte použít atribut [ordered]:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Existují další možnosti pro vytvoření objektu: výše jsme se podívali na použití rutiny
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
Rutina Add-Member umožňuje přidávat nejen vlastnosti, ale také metody k dříve vytvořenému $object pomocí konstrukce "-MemberType ScriptMethod":
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Vezměte prosím na vědomí, že jsme použili proměnnou $ScriptBlock typu ScriptBlock k uložení kódu pro novou metodu.
Chcete-li odebrat vlastnosti, použijte odpovídající metodu:
$object.psobject.properties.remove('Name')
Vytváření vlastních tříd
PowerShell 5.0 zavedl možnost definovat
class MyClass
{
# тело класса
}
Toto je skutečný typ .NET Core s tělem, které popisuje jeho vlastnosti, metody a další prvky. Podívejme se na příklad definování nejjednodušší třídy:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Chcete-li vytvořit objekt (instanci třídy), použijte rutinu
$object = New-Object -TypeName MyClass
nebo
$object = [MyClass]::new()
Pojďme analyzovat strukturu objektu:
$object | Get-Member
Nezapomeňte na rozsah: nemůžete odkazovat na název typu jako na řetězec nebo používat typový literál mimo skript nebo modul, ve kterém je třída definována. V tomto případě mohou funkce vracet instance třídy (objekty), které budou přístupné mimo modul nebo skript.
Po vytvoření objektu vyplňte jeho vlastnosti:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object
Všimněte si, že popis třídy specifikuje nejen typy vlastností, ale také jejich výchozí hodnoty:
class Example
{
[string]$Name = 'John Doe'
}
Popis metody třídy se podobá popisu funkce, ale bez použití slova funkce. Stejně jako ve funkci jsou parametry v případě potřeby předány metodám:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Nyní se zástupce naší třídy může usmívat:
$object = [MyClass]::new()
$object.Smile($true)
Metody mohou být přetížené, navíc třída má
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
Náš popis práce s objekty v PowerShellu je stěží vyčerpávající. V následujících publikacích se jej pokusíme prohloubit na praktických příkladech: pátý článek série bude věnován problematice integrace PowerShellu se softwarovými komponentami třetích stran. Minulé díly najdete na níže uvedených odkazech.
Zdroj: www.habr.com