A Windows PowerShell rejtelmei
Úgy tapasztaltam, hogy nagyon kevesen tudják, hogy mi is az a PowerShell és mire jó, ezért gondoltam, hogy néhány egyszerű, de azért hasznos példán keresztül elmagyarázom a gyakorlati felhasználásának lehetőségeit.
A cikksorozat szlogenje az lehetne: szabaduljunk ki a grafikus céleszközök fogságából, és valósítsuk meg azokat a funkciókat, amelyeket eddig mindenféle internetről összevadászott, gyakran beazonosíthatatlan forrásból származó segédprogrammal oldottunk meg!
Mi az a PowerShell?
A PowerShellt a Microsoft eleinte a hagyományos DOS-prompt, a parancssor utódjaként aposztrofálta, de aztán egyre inkább egy univerzális rendszerkezelő, feladatautomatizáló platformként lett definiálva. Ez azt jelenti, hogy a PowerShell segítségével olyan, a rendszerüzemeltetésben felhasználható kifejezéseket, kisebb-nagyobb programokat lehet írni, melyekkel a Microsoft egyre több szoftverét lehet vezérelni.
Nem feltétlenül kell mindenkinek a konzolablakban gépelgetnie mindenféle parancsot. Lesznek persze ilyenek is (ez a cikksorozat azt próbálja bemutatni, hogy ez sem ördöngösség, akár otthoni felhasználói is lehetnek a PowerShellnek), lesznek olyanok is, akik mások számára készítenek szkripteket. Aztán lesznek olyanok is, akik PowerShell-alapú eszközöket használnak, és végül lesznek olyanok, akik a PowerShell képességeit felhasználva készítenek rendszergazdák számára összetett szoftvereket.
Amikor az Exchange Server 2010 grafikus kezelőfelületén kattintgatunk, akkor a háttérben PowerShell-utasítások mennek az Exchange Serverhez, amikor a Windows Server 2008 R2 Active Directory Administrative Centerét használjuk, akkor szintén powershellezünk. Azaz maga a Microsoft is egy olyan platformként használja a PowerShellt, amellyel rendszergazda eszközöket lehet létrehozni.
A PowerShell tehát egyszerre nagyon sok minden: parancssori eszköz, amellyel begépelt parancsokkal tudjuk utasítani a számítógépünket, hogy különböző műveleteket elvégezzen. A PowerShell egy programnyelv is, minden ehhez szükséges jellemzővel: ciklussal, vezérlőutasításokkal, operátorokkal, változókkal, adattípusokkal. A PowerShell a rendszergazdák számára egy olyan eszköz, ami a .NET keretrendszer profi programozók által létrehozott több ezer osztály objektumait és azok szolgáltatásait elérhetővé teszi. És végül számomra, mint informatikai oktatónak egy olyan, mindenki számára elérhető eszköz, amivel mind a Windows operációs rendszerek belső működését, mind az objektum-orientáltságot, mind a programozást nagyon jól meg lehet tanítani.
Az első gyakorlat
Mindennek demonstrálására az első feladat az lenne, hogy kicsit tegyük rendbe a számítógépre áttöltött fényképeinket. A mai digitális fényképezőgépekben található nagy tárolókapacitású memóriakártyák mellett gyakran több száz fényképünk is összegyűlik a „My Pictures” könyvtárban, elég nehéz köztük tájékozódni. Ebben a cikkben addig jutunk el, hogy a képeinket havi bontásban átrakjuk alkönyvtárakba.
A Microsoft Windows 7 érkezésével minden ilyen operációs rendszeren ott van a Windows PowerShell. A többi, de azért Windows XP-nél nem régebbi Microsoft operációs rendszert használók pedig ingyen letölthetik és telepíthetik. Nézzük az első lépést, nyissuk meg a PowerShellt, illetve a kezdőknek talán kényelmesebben használható grafikus szerkesztő felületet, a Windows PowerShell ISE-t!
Ennek a háromosztatú ablaknak a felső részében fogunk dolgozni. A begépelt parancsokat a „Run Script (F5)” gombbal tudjuk futtatni, az eredmények a középső ablakrészben jelennek meg. Itt a cikkben félkövérrel jelzem azt, amit a felső ablakrészbe kell gépelni. Mindig csak annyi legyen a felső részben, amennyit én itt jelzek, a korábbi parancsokat mindig töröljük ki! Eltérő háttérszínnel az látható, ami a kimeneti ablakrészben jelenik meg. Ahol nagyon sok sor jelenne meg a kimeneten, ott csak az első néhányat másoltam ide.
Kezdjünk neki! Feltételezem, hogy a képek a Pictures könyvtárban találhatók.
cd .\\Pictures
dir
Directory: C:\\Users\\tibi\\Pictures
Mode LastWriteTime Length Name
- - - -
-a- 2009.09.02. 22:58 2525150 P1090919.JPG
-a- 2009.09.02. 22:58 2256418 P1090927.JPG
-a- 2009.09.02. 22:58 2278723 P1090998.JPG
-a- 2009.09.02. 22:59 2499729 P1100022.JPG
-a- 2009.09.02. 22:59 2526647 P1100042.JPG
-a- 2009.09.02. 22:59 2282924 P1100125.JPG
…
Ez egyelőre még nem túl izgalmas. Azt hisszük, hogy DOS parancsokat használunk, de ez már színtiszta PowerShell, valójában a cd a Set-Location, a dir pedig a Get-ChildItem PowerShell parancsok \"álneve\". Az igazi érdekesség ott jön elő, ha elkezdünk dolgozni az egyes fájlokkal. Elöljáróban annyit kell tudni, hogy a PowerShellben minden objektum, hogy vannak lekérdezhető és esetleg átírható tulajdonságai,és meghívható metódusai. A metódusok olyan függvények, parancsok, amelyek az adott objektummal kapcsolatban valami értelmes dolgot hajtanak végre. A mi képrendezgető feladatunk szempontjából most a képfájl azon tulajdonsága érdekes, ami a módosításának dátumát tartalmazza. Nézzük, ezt hogyan érhetjük el egy konkrét fájl esetében:
(dir .\\P1090919.JPG).lastwritetime
2009-09-02
A zárójelek közti rész egy konkrét fájlt \"megragad\", majd ennek a fájlnak vesszük a lastwritetime tulajdonságát. A \"pont\" karakterrel lehet hivatkozni az objektumok tulajdonságaira.
Nekem ebből az év és a hónap kellene számokkal kifejezve, szépen egybefűzve egy kötőjellel, mert ilyen nevű alkönyvtárakba szeretném rendezni a képeimet. Szerencsére az előző kimenetet nem szövegként kell feldolgoznunk (az elég nehéz lenne), hanem erre a PowerShell kész megoldással áll rendelkezésünkre. Miután itt egy dátumról van szó, előveszem a dátumok kezelését végző parancsot, a get-date-et és megadom a megfelelő formázó kifejezést a –Format paraméternév után:
get-date (dir .\\P1090919.JPG).lastwritetime -Format \"yyyy-MM\"
2009. szeptember 2. 22:52:57
Ez a formázás tehát veszi a dátumból az évek számjegyeit (yyyy), egy kötőjelet, majd a hónapok számának két számjegyét (MM – itt kivételesen fontos a nagybetű, mert kisbetűvel a perceket jelöljük). Na, ez már egy fájlra működik, most nézzük az összes képfájlra ezt hogyan tudjuk ezt előállítani:
dir *.jpg| ForEach-Object {get-date $_.lastwritetime -format \"yyyy-MM\"}
2010-02
2009-09
2009-09
2009-09
...
Mi is történt itt? A dir-t értjük, az ebből kijövő fájlobjektumokat továbbküldjük a \"futószalagon\" (| jel) további feldolgozásra. Ezen feldolgozás keretében minden egyes futószalagon érkező objektumra a Foreach-Object parancs segítségével legeneráltatjuk az előbb már látott módszerrel az év-hó formátumú számsort. Az éppen aktuális futószalagon érkező objektumra, jelen esetben fájlra, a $_ jellel tudunk hivatkozni. Fontos, hogy a ForEach-Object utáni kifejezés kapcsos zárójelben van, ennek fontos szerepe van, amire majd egy következő cikkben térek ki.
Ezután alakítsuk tovább a kis programunkat! Ebben a lépésben ellenőrizzük, hogy év-hó formátumú alkönyvtár már létezik-e? Ezt a Test-Path PowerShell paranccsal lehet megtenni. Ennek működésének felderítésére vegyünk fel egy alkönyvtárt ide, a fényképek könyvtárába, mondjuk \"egyéb\" névvel. Ez után ellenőrizzük, hogy ez mit ad eredményül:
Test-Path \".\\egyéb\"
True
Ez egy nem létező könyvtárra False eredményt fog adni. Nekünk meg pont ekkor kellene alkönyvtárt létrehozni, amikor ez a vizsgálat hamis eredményt ad. Programozásban jól ismert az IF vezérlőszerkezet, mellyel akkor lehet végrehajtatni valamit, amikor egy feltétel igaznak értékelődik. Nekünk hamis eredményt ad a Test-Path, amikor tennivalónk lenne, így fordítani kell a kiértékelés eredményén, amit a Test-Path eredményének „negálásával” tudjuk elérni, amit a PowerShellben a felkiáltójellel tudunk jelezni. Mindezzel együtt az If szerkezet így néz ki:
If(!negálandó feltétel){végrehajtandó kód}
Könyvtárat a New-Item paranccsal tudunk létrehozni, a következő formátumban:
New-Item –Path hova –ItemType Directory
Fájlt átmozgatni a Move-Item paranccsal tudunk, melynek szerkezete a következő:
Move-Item –Path –Destination célkönyvtár
Még annyit tegyünk meg, hogy az alkönyvtárnevet tegyük be egy változóba, hiszen ezt többször is fel fogjuk használni: az alkönyvtár meglétének ellenőrzésekor, az esetlegesen létrehozandó új könyvtár esetében és a kép átmozgatásának célkönyvtáraként. Változóneveket a PowerShellben egy $ jellel kell kezdeni. A PowerShellben akár ékezetes karaktereket is alkalmazhatunk változónevekben.
A teljesen összerakott kis \"program\" így néz ki:
cd $HOME\\pictures dir *.jpg | ForEach-Object { $alkönyvtár = get-date $_.lastwritetime -Format \"yyyy-MM\" if(! (Test-Path -Path \".\\$alkönyvtár\")) { New-Item -Path \".\\$alkönyvtár\" -ItemType Directory} Move-Item -Path $_.pspath -Destination \".\\$alkönyvtár\" }
Mit is láthatunk itt? Az elején – biztos, ami biztos – átlépünk a képek könyvtárába, nehogy véletlenül másutt levő képfájlok között garázdálkodjunk. A $HOME változó tartalmazza a belépett felhasználó munkakönyvtárát, feltételezésem szerint ennek Pictures alkönyvtárában vannak a képek. Ezután a JPG kiterjesztésű fájlokat megragadjuk, rátesszük a futószalagra és beküldjük őket egy ForEach-Object \"gépbe\". A gépbe belátunk, a belső felépítés a kapcsos zárójelek között látható. A gép belsejében létrehozunk egy alkönyvtár nevű változót, ami a gépbe érkező fájl módosítási idejéből képződő kötőjeles számjegyeket tartalmazza. Majd megvizsgáljuk, hogy van-e ilyen nevű alkönyvtár, és ha nincs, akkor létrehozzuk azt. Mire a Move-Item-hez érünk, addigra már biztos van megfelelő alkönyvtár, így az éppen feldolgozás alatt levő képfájlt át tudjuk oda helyezni.
Mik ebben a programban még az érdekességek? Például az, hogy a PowerShell a változókat az idézőjelek között kifejti, így a \".\\$alkönyvtár\" kifejezés mindig az aktuális alkönyvtárnévvel helyettesítődik be a . és / jel után. Kérek mindenkit, hogy a program tesztelését csak olyan fájlokon végezze, amelyekről van biztonsági másolata, mert félregépelések esetén esetleg olyan helyre mozgatódnak, ahol nehéz megtalálni azokat.
Tovább is van, mondjam még?
Ha sikerült felkeltenem az érdeklődést a PowerShell iránt, akkor szívesen fogadok javaslatokat, hogy milyen példákon magyarázzak tovább, milyen egyszerűbbnek tűnő feladatok megoldása nehézkes a meglevő eszközkészlettel. Biztos lesznek olyanok, akik számára ez túl alapszint, de esetleg vannak olyanok is, akiknek ez túl bonyolult, követhetetlen. Ezt is jelezzétek!
Soós Tibor (PowerShell MVP, MCT), IQSOFT – John Bryce Oktatóközpont