Pokud vyvíjíte na Windows a skripty stále píšete jako BAT / CMD soubory, hodně si dlužíte. Sám jsem takovým dlužníkem dlouho byl, ale jelikož to na současném projektu myslíme s automatizací vážně a nějakou skriptovací technologii jsem se stejně chtěl naučit, PowerShell pomalu poznávám a je to poměrně příjemná zkušenost. Pokud jste se zatím pro přechod neodhodlali, třeba vás trochu tímto článkem nahlodám.
Vše, co budu popisovat, popisuji pohledem začátečníka. Myslím, že mám docela dobrou představu o tom, jak PowerShell funguje, ale pokud budu někde technicky ne zcela přesný, tak mi to prosím odpusťte, případně mě vy zkušenější v komentářích opravte.
Proč PowerShell a ne X, Y nebo Z
PowerShell není zdaleka jedinou volbou pro skriptování na Windows. Velmi obecně bych řekl, že se ke skriptování dá použít celkem cokoliv, co je aspoň trochu dynamické, takže validními možnostmi jsou jazyky typu PHP (skrze PHP CLI), Python nebo Ruby, a zajímavou možností je i JavaScript + Node.js (dost jsem to zvažoval; no nevypadal bych pak víc cool? :) ).
PowerShell má ale podle mého názoru jednu zásadní výhodu: jedná se o “oficiální” Windows technologii. Tím teď nemyslím jen to, že je předinstalován jak na klientském, tak serverovém operačním systému, ale např. všechno na Windows 8 Serveru by mělo fungovat bez GUI a správa aplikací bude probíhat přes PowerShell. Řada produktů od Microsoftu tak již funguje, např. klikací administrace Exchange Serveru je nadstavbou nad PowerShellem, cmdlety (příkazy) existují i pro IIS, SQL Server a tak dále. I vývojářské věci se čím dál častěji spoléhají na PowerShell, například NuGet nebo migrace Entity Frameworku.
Pokud tedy ve svém deployment skriptu potřebujete aktualizovat databázi, vytvořit novou webovou stránku, případně ji aktualizovat, nastavit něco v IIS a podobně, je PowerShell přirozenou volbou. Plus samozřejmě umí běžné věci jako procházení adresářů, hledání obsahu, třídění, má slušný dynamický jazyk atd.
PowerShell je hezký
Nebudu zastírat, že jsem člověk, který zrovna dvakrát příkazovou řádku nemiluje. Pokud k něčemu existuje GUI, téměř automaticky jdu do něj, ale když už je příkazová řádka nezbytností, dokážu ocenit její eleganci. Takže zatímco např. v Gitu / Bashi jsem poměrně ztracený a utíkám do TortoiseGitu vždy, když je to jen trochu možné, PowerShell se mi kupodivu líbí. Zde jsou věci, které mě jako začátečníka zaujaly nejvíc:
- PowerShell pracuje s objekty. Když uděláte
dir
, výstupem je sice nějaký výpis na obrazovku, ale to je jakoby druhořadé – především dostáváte sadu objektů, které přes pipu můžete předat dalšímu příkazu, ten je může nějak transformovat a předat dál jako další sadu objektů, vyexportovat do CSV, udělat nad nimi introspekci (reflexi) atd. atd. Jednotlivé cmdlety si tak mezi sebou dokáží předávat hodně obecné množiny dat a celé to dohromady funguje až trochu magicky (sortování, projekce, import, export atd. celkem nad čímkoliv, fakt je to hezky navržené). - Pokud znáte .NET, získá pro vás PowerShell úplně novou dimenzi. Zavolat lze libovolnou metodu z libovolné assembly, takže např. místo
dir
můžete zavolat nějakou metodu na tříděDirectoryInfo
, a výstup je přitom pořád jen nějaká PowerShell množina, se kterou lze standardními prostředky pracovat dál. I vestavěné datové typu jsou .NET typy, takže třeba na řetězci můžete udělat vše, co lze v .NETu se Stringem. Tohle je naprosto boží. - Shell má dobré doplňování kódu. Doplňuje nejen názvy cmdletů (příkazů), ale i jejich parametrů. Protože je toto systémová věc, můžou nad PowerShellem vzniknout inteligentní editory, ve kterých funguje Ctrl+mezerník apod. (doporučuji např. PowerGUI).
- Všechno je dobře zdokumentované, a pro dokumentaci se používá standardizovaný formát, takže i případné knihovny třetích stran mívají dobrou dokumentaci. Společně s předchozím bodem to vede k tomu, že PowerShell má dobrou “discoverability”, tj. nemusíte tak často na Google, zkušený PowerShellista většinu věcí zjistí z helpu nebo z vestavěné reflexe (
gm
,Get-Member
). - Celé prostředí je konzistentní. Cmdlety jsou pojmenované podle konvence Verb-Noun, např.
Get-ChildItem
, takže pokud zhruba tušíte, co chcete udělat, zadáte sloveso a mačkáte Tab (současně, pokud už příkazy znáte, pro většinu věcí existují aliasy, takže např.Get-ChildItem
lze zapsat jakodir
,ls
nebogci
– vybere si každý). Další krásnou ukázkou konzistence jsou takzvaní PowerShell poskytovatelé – pokud jednou umíte vylistovat obsah adresáře pomocídir
, tak umíte vylistovat i seznam proměnných prostředí (dir env:
), registrů (dir HKCU:
), dostupných funkcí (dir function:
) atd. – všechno to jsou jen virtuální “disky”, na kterých můžete dělat běžné operace jakodir
,cd
,del
apod. Tento koncept se mi moc líbí.
Problematické části PowerShellu
Nečekali jste ode mě, že bych byl nekritický, že? Takže, tady je pár věcí, které myslím, že od PowerShellu můžou trochu odrazovat:
- Spouštění je problematické. Bohužel, napsat PowerShell skript pro někoho cizího znamená, že ten někdo bude mít víc práce než poklepat na *.bat, možná si skript ani v extrémním případě nespustí (pokud není na PC administrátor a skripty jsou zakázané). Pro použití na našem projektu toto není problém, protože v PowerShellu píšeme interní skripty, ale určitý zádrhel to je.
- Když jsem někdy potřeboval rychle sesmolit nějaký BAT skript, většinou jsem řešení našel na Googlu a byl jsem rychle hotový. S PowerShellem jsem brzy poznal, že bez znalosti základních konceptů jsem dost ztracený – často jsem nevěděl, co nějaká vygooglená řádka kódu dělá a jak je možné, že vůbec funguje. Naučení se konceptů a získání určité základní praxe s PowerShellem pár dní trvalo, ale zase to vnímám jako velmi dobrou investici. V blízké době blognu seznam zdrojů, které mi s učením pomohly.
- Jak je znalost .NETu výhodou, tak je jeho neznalost určitou nevýhodou. Základní i docela pokročilejší věci sice uděláte s vestavěnými příkazy, ze kterých .NET nijak nečouhá, ale pro využití skutečného potenciálu může znalost .NETu trochu chybět, ač ne moc.
Jiné větší problémy ale zatím nevidím.
Celkově PowerShell považuji za velmi důstojnou a vydařenou skriptovací technologii pro Windows. Mrkněte na ni.
Děkuju! Na další články o PowerShellu se těším – až budu zas dělat nějakou admin-práci ve Windowsech, snad už nebudu muset brblat nad absencí bashe :)
Přidal bych jedno negativum: rychlost/výkon
Obzvlášť v porovnání s Unix/Linux shelly na mě vždycky PowerShell působí jako neskutečný šnek, který si něco v pozadí pár sekund chroustá i u naprosto primitivních příkazů.
Mohu se zeptat jak moc využíváte možnost pracovat s výstupem jako s objekty? Přes deset let pracuji v linuxu s konzolí a nějak si nedokáži představit něco kvůli čemu bych to při běžném používání potřeboval. Neberte to prosím jako provokaci, ale jen jako zvídavou otázku.
@pm například map/filter/reduce bez nutnosti grepování.
@Aleš Roubíček: hm, grepování zrovna používám natolik přirozeně že mě nějak nezdržuje. Jak je to třeba ve srovnání rychlosti? Zajímala by mě reakce na @Vojtěch Kusý
@Vojtěch O relativní pomalosti PowerShellu jsem slyšel (myslím, že i od Aleše), ale zatím jsem na to nenarazil. Můžeš prosím uvést nějaký příklad, který bych si mohl vyzkoušet a kde by byla pomalost evidentní?
@pm Linux shell jsem používal jen velmi zběžně, takže nemůžu srovnávat, ale líbí se mi, že třeba v tomto příkazu:
může být
xyz
skoro cokoliv a pořád to bude fungovat.Tady je menší ukázka scriptu, který projde všechny manifest.xml, z XML vybere jen elementy, které potřebuju, seřadí je a vyexportuje do CSV.
https://gist.github.com/2049505
Jde nastavit, aby si okno power shellu pamatovalo historii zadaných příkazů i po opětovném spuštění?
@Petr
Myslím, že ne(edit: viz odpověď níže od @stej), ale do profilu jde přidat cokoliv, co člověk používá často.Jde toho hodně, viz. např. PowerShell 2.0 – Persisting Command History
@stej: To je snad v kazdym shellu samozrejmost, ne? Proc to neni v zakladu? (linuxova opice bez provokaci)
@starenka Proč to není v základu, to nevím. Osobně to ale asi tolik nepotřebuju.. Jaký je tvoje workflow, kde se ti to hodí? Přijde mi, že pokud to potřebuju znovu, udělám si na commandy aliasy/funkce a nemusím řešit, kdy jsem co jak volal. Případně byly i pluginy do ISE (grafická verze konzole), ale to už jsme jinde..
@stej Moje workflow je, ze zmacknu (de fakto v jakymkoliv shellu) ctr+r a napisu par pismen – cimz prohledavam historii. Jasne, aliasy nebo posejvovany zvlast vyzivny pajpobrani taky vedu, ale historie je dulezita. Nedokazu si predstavit, ze pustim shell a sipka nahoru mi nerekne, co jsem udelal.