Objekty a roury
Důležité vlastnosti
Když někomu řeknete, aby vám vysvětlil výhody PowerShellu, většinou se dozvíte, že jednou z nich je objektová roura. Mechanismus roury už většina z vás asi použila (nebo jste o ní alespoň slyšeli), horší to už bude zřejmě s tou její objektovostí. Práce s objekty vychází z toho, že PowerShell je postavený na platformě .NET Framework (vzpomínáte si, když jsme si v první části, že bez .NETu PowerShell nenainstalujete?). V dnešní části si povíme právě o objektech a rouře. O .NETu si povíme příště.
Objekty
Začněme obecným vysvětlením principu objektů. Ti z Vás, kdo máte znalosti jakéhokoli objektového jazyka, můžete tuto část přeskočit. Rovnou se omlouvám některým .NET puristům – určité části budu záměrně zjednodušovat. Tento článek je psán z pohledu administrátora a (v tuto chvíli) není nutné vědět, co je například konstruktor.
Při svých prezentacích PowerShellu pro lidi zabývající se administrací systémů jsem zjistil, že některým z nich dělá problém pochopit základní princip. Ukazuji jim tedy analogii na lahvích různých tvarů a náplní. Při druhém vyprazdňování flašky s rumem je jim to již většinou jasné. Na stránky seriózního média, jakým bezesporu TechNet je, ovšem alkohol nepatří a tak se spokojíme s něčím méně kontroverzním. Upustíme od tradičních žárovek nebo aut a přeneseme si do objektů svět zvířat – budeme pracovat s objektem kočkovitá šelma.
Každý objekt si sebou nese sadu vlastností a metod (funkcí).V případě kočky mezi vlastnosti patří např. velikost, barva chlupů, barva očí, váha či oblíbené jídlo. Řeknu-li tedy, že máme kočku oranžové barvy s černými pruhy, váhou 250kg, velikostí XXXL, která pojídá s oblibou buvoly, bude vám jasné, že mluvím o tygrovi. Pokud taková kočka váží šest kilo, je tříbarevná, velikosti M, má ráda šunku a její oblíbené místo k válení je klávesnice mého notebooku, asi tušíte, kde byste takovou kočku hledali.
Stejně tak to je s objekty v počítačovém světě. Pokud se budeme bavit například o procesech jsou jejich vlastnostmi ProcessName, WorkingSet, StartTime nebo Id. Vlastnosti popisují určitý stav objektu v čase, pokud chcete takový stav změnit, použijete k tomu určené metody.
Kočka má například metody spát, jíst, značkovat, vrnět nebo plést se pod nohy. Pokud u kočky spustíte metodu spát, můžete se jít v klidu dívat na televizi (dokud nevyvoláte u kočky metodu probudit se, například otevřením dveří od ledničky). U procesů je to podobné (s tou výjimkou, že procesy naštěstí na ledničku nereagují), zavoláním určité metody změníme chování nebo stav procesu. Existují například metody Start(), Refresh() nebo Kill().
Všimněte si, že jsem za názvy metod psal kulaté závorky. Berte to jako mnemotechnickou pomůcku, pokud uvidíte při práci s objekty závorky, pracujete s metodou.
Objekty a objektový přístup obecně, mají jednu obrovskou výhodu. Relativně jednoduše s nimi dokážeme pracovat pomocí základních příkazů. Když jsme si šli vybírat do útulku objekt kočka, věděli jsme, že chceme určitou velikost, barvu, roztomilost a způsob chování (samozřejmě že to dopadlo úplně jinak, ale to nebyla chyba objektového přístupu, ale změny vstupních parametrů v okamžiku vstupu do místnosti plné mňoukajících koťátek). U procesů je to naštěstí exaktnější. Počítač vám běží pomalu a tak hledáte process, který zabírá nejvíc procesorového času či paměti a na ten se zaměříte. „Zmrzla“ vám určitá aplikace a tak hledáte process s jejím jménem, abyste ho ukončili, resp. zavolali nad oním procesem metodu Kill().
Některé z typů objektů (s jejich vlastnostmi a metodami) jsou vypsány v následující tabulce. Co je třída si řekneme na konci dnešního článku.
Jméno
Třída
Vlastnosti
Metody
Proces
System.Diagnostics.Process
ProcessName, WorkingSet, StartTime
Start(), Refresh(), Kill()
Služba
System.ServiceProcess.ServiceController
DisplayName, Satus, DependentServices
Start(), Stop(), Pause()
Soubor
System.IO.FileInfo
Name, Length, LastAccessTime
Open(), Delete(), Delete()
Klíče registru
Microsoft.Win32.RegistryKey
Name, SubKeyCount, ValueCount
OpenSubkey(), GetValue(), DeleteValue()
Datum
System.DateTime
Date, Hour, DayOfWeek
Add(), AddDays(), ToUniversalTime()
Text
System.String
Length
CompareTo(), Contains(), ToLower()
Přístup k vlastnostem a metodám objektů
Než si ukážeme jak přistupovat k vlastnostem a metodám objektů hromadně pomocí roury, ukážeme si, jak k nim přistupovat v případě jednoho objektu. V následujících ukázkách si nejdříve uložíme textový řetězec do proměnné ($text) a poté budeme přistupovat k jednotlivým vlastnostem a metodám.
Za chvíli si ukážeme, jak zjistit, které vlastnosti a metody lze pro konktétní typ objektu použít.
Tip: PowerShell podporuje doplňování příkazů pomocí klávesy tabulátor <Tab>. Pokud byste v předchozím příkladu napsali $te<Tab>.Le<Tab>, PowerShell zápis doplní na správnou formu ($text.Length). Tabulátorem můžete „cyklovat“ mezi možnými variantami – v případě, že napíšete pouze $text. (tečka je zde důležitá), můžete opakovaným použitím klávesy <Tab> procházet všechny dostupné vlastnosti a metody.
Další možností je doinstalovat nástroj PowerTab, který po stisknutí <Tab> zobrazí dostupné vlastnosti a metody přehledněji.
Roura
Mechanismus roury (v angličtině pipeline) se ve výpočetní technice používá od sedmdesátých let, kdy byla tato technika implementována do operačního systému UNIX. Její idea je geniálně jednoduchá: „Vezmi výstup jednoho příkazu a pomocí roury jej pošli na vstup příkazu dalšího.“ Roura se zapisuje pomocí znaku | a byla dostupná již v dřívějších verzích operačních systémů Microsoftu. V cmd.exe (nebo již v MS-DOSu) jste ji mohli bez problémů použít např. pro stránkování dlouhých výpisů:
C:\>dir /b /s *.txt | more
Výstup příkazu dir (seznam txt souborů) je poslán na vstup příkazu more, který zajistí zastavení výpisu po zaplnění obrazovky. V PowerShellu můžete rouru použít třeba takto:
PS C:\> dir *.ps1 | Sort -Property Length
Na výstupu příkazu dir jsou objekty (kolekce objektů) a každý z nich reprezentuje jeden soubor s příponou PS1. Tyto objekty jsou pomocí roury předány na vstup příkazu Sort, který je vezme a setřídí je podle vlastnosti Length. Na výstupu příkazu Sort máme tedy soubory PS1 seřazené podle velikosti (opět se zde nacházejí ve formě kolekce objektů, takže bychom je mohli další rourou poslat jinému příkazu). PowerShell ví, že vlastnost Length je číselný údaj a že s ním má tedy jako s číslem pracovat. Stejně tak ví, že když napíšeme
PS C:\> dir *.ps1 | Sort -Property LastWriteTime
chceme řadit soubory podle časového údaje a sám provede potřebné úkony. Pokud tedy pracujeme s objekty v rouře, stačí vědět, kterou vlastnost potřebujeme pro dosažení potřebných výsledků.
Pojďme si ukázat ještě pár jednoduchých příkladů a potom si řekneme, jak vlastně zjistíme, které vlastnosti obsahuje konktétní typ objektu.
Příkaz
Výsledek
dir | Sort -Property Length -Descending | Select -First 5
Pět největších souborů v adresáři
dir | Group -Property Extension | Sort -Property Count -Descending
Jednotlivé typy souborů, řazené podle počtu
dir | Measure-Object -Property Length -Sum
Celková velikost souborů v adresáři
Get-WmiObject Win32_LogicalDisk | `
Select Name, DriveType, FileSystem, Size, FreeSpace | `
Format-Table -AutoSize
Vypíše logické disky, jejich jméno, typ, souborový systém, velikost disku a volné místo. Výsledek zobrazí v tabulce.
Get-Process -Name notepad | Stop-Process
Ukončení notepadu
U posledního příkladu je dobré si uvědomit jednu věc – PowerShell najde všechny procesy, které se jmenují notepad a pošle je rourou dále. Stop-Process převezme opět všechny procesy a zastaví je. Pokud byste se překlepli a provedli následující příkaz (nezkoušet!!!)
Get-Process | Stop-Process
způsobili byste svému počítači (s Windows XP) modrou smrt, protože byste zastavili všechny běžící procesy. Abyste takovým věcem zabránili, existují v PowerShellu příkazy a přepínače, které si ukážeme v některém z následujících článků.
Zjištění vlastností a metod objektu
Nyní si ukážeme, jak zjistit, které vlastnosti a metody obsahuje konkrétní objekt. V PowerShellu je k tomuto účelu cmdlet Get-Member. Bez přehánění můžu prohlásit, že to je nejužitečnější cmdlet, který existuje. Ukažme si jeho použití nejprve na jednoduchém řetězci znaků (výstup byl zkrácen).
Vidíte, že řetězec má jednu vlastnost (Length) a množství metod (ve skutečnosti je jich 35). Jak je použít jsme si ukázali před chvílí. Pojď me si zobrazit vlastnosti objektu typu soubor.
Zde vidíte, jak jsem zjistil, že existuje vlastnost LastWriteTime.
Get-Member je opravdu vynikající průzkumník a pomocník. Zvláště ze začátku jej budete používat velice často.
Ještě jednu věc je potřeba zmínit. Všechny objekty stejného typu (např. procesy) jsou odvozeny od tzv. třídy. Třída říká, jaké vlastnosti a metody bude objekt mít. Nemusíte si pamatovat, že proces (např. notepad.exe) je vlastně odvozen od třídy System.Diagnostics.Process. Je ale dobré vědět, kde tuto informaci hledat pro případ, že byste chtěli např. na MSDN hledat podrobnější informace o objektu. Příkaz Get-Member vám tuto informaci zobrazí v první řádce výpisu.
Můžete také použít následující kus kódu (schválně jsem použil relativně složitý a nečitelný zápis – chci vás tím nalákat na další část, kde si povíme mimojiné o aliasech):
Příkaz dir můžete změnit za jakýkoli jiný, který vás zajímá. Chcete-li ověřit, že text „Ahoj“ je opravdu string, můžete použít