Építsünk rendszergazda eszközt PowerGUI alapon!

A PowerGUI egy olyan eszköz (most nem annak script editoráról, hanem az „igazi” PowerGUI-ról beszélek), mellyel grafikus rendszergazda eszközöket lehet építeni olyanok számára, akik nem ismerik a PowerShell nyelvezetét, és nem is éri meg ezt nekik megtanulni, mert ők csak ritkán vagy pedig csak egy szűk alkalmazási területen használnák azt. És az igazán nagyszerű ebben a szoftverben, hogy olyanok építhetik meg ezeket az eszközöket, akik nem „igazi” fejlesztők, hanem „csak” rendszergazdák, akik jól ismerik a PowerShellt. Azaz nem kell Visual Studio-t használni, nem kell fordítani, hanem közvetlenül PowerShell segítségével építhetők grafikus eszközök.

Ebben a fejezetben a PowerGUI-ban történő fejlesztés főbb elemeit ismertetem, mert ez hordoz magában jó néhány tanulságot, amely az általános PowerShell ismereteinket is mélyíti.

Faelemek, rács és a tevékenységek

Elsőként nézzük át a főbb elemeit a PowerGUI felületének, melyek úgy kapcsolódnak egymáshoz, mint a LEGO építőkockák elemei és együtt adnak ki egy összetettebb funkciót. A PowerGUI ablak bal oldalán építhetjük fel egy fastruktúrában a szkriptjeinket. Ez sokkal hatékonyabb tárolási lehetőség, mint hogyha a szkriptjeinket a fájlrendszerben helyeznénk el. Persze van néhány lényeges különbség a PowerGUI-ban és a fájlrendszerben tárolt szkriptek lehetőségei között, erre majd hamarosan visszatérek.

Nézzük tehát azt, hogy hogyan tudjuk ezt a fastruktúrát kialakítani! A felvehető faelemek a következők: mappa (folder), csomópont (node) és szkript-csomópont (script node).

69 . ábra PowerGUI csomópontok

Igazából nincs nagy különbség a három típus között, bármikor átalakítható egyik a másikba. A mappa csomópontok szerep igazából a további csomóponttípusok összefogása, csoportosítása. A „sima” csomópont egy meglevő cmdletet futtat, akár paraméterezhető módon. Ezt viszonylag ritkán használjuk. Az igazi lehetőségeket a szkript-csomópont rejti. Egy ilyen csomópont mögött olyan szkriptet lehet tárolni, aminek valamilyen kimenete van:

70 . ábra Az első szkript-csomópontom

A fenti példámban a szkriptem egy egyszerű kis szövegfájl-listázó műveletet hajt végre, méghozzá olyan módon, hogy a kimeneten a fájlnév és a teljes elérési út mellett a fájl tartalmának első sora is látható legyen. Ha ezt az ablakot az OK-val lezárom, vagy később bármikor erre a csomópontra kattintok, akkor a fenti szkript lefut és az eredmény az PowerGUI ablak középső részén jelenik meg:

71 . ábra A csomóponti szkript kimenete

Ez még idáig helyettesíthető lenne nagyjából az Out-GridView kimenettel is, hiszen itt is lehetne oszlopfejléceket eltüntetni, sorba rendezni, szűrni, stb. Az igazi egyedi lehetőség, amitől ez rendszergazda-eszköz lesz, hogy a jobboldali „Actions” részben újabb szkripteket lehet definiálni, melyek az eredményrácsban kijelölt elemeken valamit végeznek:

72 . ábra Cselekvési lehetőségek

A Category segítségével elválasztó címkéket vehetünk fel. Az Action lehetőséggel egy meglevő cmdletet futtathatunk, ami megint csak nem a mi igazi terepünk. A harmadik lehetőség, a Script Action kell nekünk!

73 . ábra A szkript-tevékenység sablonja

Látható, hogy egy kis keretprogramot, sablont ad rögtön nekünk a PowerGUI, ebben láthatjuk, hogy a középső ablakrészben kiválasztott objektumok lesznek majd benne az $input változóban, és ezeken hajtódik végre rendre egy ForEach-Object ciklussal az, amit mi megírunk. Azonban vigyázzunk! A tevékenységek nem csomóponthoz-kötöttek, hanem objektumtípushoz! Azaz elég egyszer definiálni egy tevékenységet, az innentől kezdve automatikusan megjelenik minden olyan esetben, amikor bármelyik csomópontra is kattintunk, de a rácsban az adott objektumtípus jelenik meg. Ezt az típus-hozzárendelést a Display Configuration gomb megnyomásával láthatjuk, illetve állíthatjuk be:

74 . ábra A tevékenység összerendelése objektumtípussal

Konkrétan most ez nem is lesz így jó nekünk, mert az én példámban a csomóponti szkript az PSObject-et, azaz hosszú nevén System.Management.Automation.PSCustomObject-et ad a kimenetén, ami túl általános, így nagy a veszély, hogy olyan csomópontoknál is megjelenik, ahol nem is szövegfájlok szerepelnek a háttérben. Szerencsére ez az objektumtípus annyira egyedi, hogy új nevet is adhatok neki, így a csomóponti szkriptet az alábbi módon módosítom:

Get-ChildItem c:\PowerGUITeszt\*.txt | ForEach-Object {

     $o = New-Object -TypeName PSObject -Property @{

          filename = $_.name;

          elsősor = @(Get-Content $_)[0]

          fullname = $_.fullname

     }

     $o.PSObject.TypeNames.Clear()

     $o.PSObject.TypeNames.Insert(0,'En.Sajat.Egyedi.Osztalyom')

     $o

}

Látható, hogy most az $o változóban kezdem felépíteni az egyedi objektumomat, melynek a típusneveket tartalmazó tulajdonságát törlöm, majd feltöltöm egy általam kitalált egyedi tulajdonságnévvel, majd az így módosított objektumot teszem ki a kimenetre.

Legyen az első tevékenység-szkriptem az, hogy a kijelölt fájlok tartamát jelenítem meg!

 

75 . ábra Tevékenység-szkript és a képernyőjének beállítása

Látható, hogy most már ez a szkript az én egyedi típusomhoz van rendelve, ráadásul létrehoztam egy „Saját cselekvéseim” kategóriát is, hogy elkülönüljön ez a tevékenység „gyári” tevékenységektől. És ami fontos még, hogy a „Display results” csoportban a beágyazott nézetet kértem (Display the results in a nested view), hiszen ha nem ezt tenném, akkor nem is igazán látnék semmit, mert a tartalmat a meglevő rácsban nem tudná megjeleníteni, hiszen az teljesen más objektumtípusok megjelenítésére van kialakítva.

Nézzük, most mi lesz, ha rákattintok az elkészült „Teljes tartalom megjelenítése” menümre:

76 . ábra Tevékenység-szkript eredménye

Látható, hogy a középső ablakrészben egy újabb „réteg” képződött, ahol a tevékenység-szkript eredménye vált láthatóvá. Konkrétan én most eredetileg két fájlt is kijelöltem, és mindkettő tartalma van most az ábrán soronként. Visszalépni a korábbi rácshoz a középső rész fejlécében kialakult menüstruktúra „Szkript csomópont” részére kattintva lehet.

Nézzünk most egy „még igazibb” tevékenységszkriptet, mondjuk ez csinálja azt, hogy a kijelölt szövegfájljaim első sorának az elejére beilleszti az aktuális dátumot.

# Type in a PowerShell script here

$input | ForEach-Object {

    # add your processing for each item from the grid selection

    # the $_ variable represents each individual object

     $sorok = Get-Content -Path $_.fullname

     if($sorok[0] -match '^\d{2}/\d{2}/\d{4}\s\d{2}:\d{2}:\d{2}\s'){

     $sorok[0] = $sorok[0] -replace '^\d{2}/\d{2}/\d{4}\s\d{2}:\d{2}:\d{2}\s',

          "$(Get-Date) "

     }

     else {

          $sorok[0] = $sorok[0] = [string] (Get-Date) + " " + $sorok[0]

     }

     $sorok | Set-Content -Path $_.fullname

}

És ennek megjelenítési beállításai:

77 . ábra Kimeneti objektumokat módosító tevékenység megjelenítési beállítása

Itt már nem beágyazott kimenetet kértem, hiszen ugyanazon objektumokat módosítottam, mint amit a csomóponti szkript megjelenített, így csak annyi a feladat, hogy a meglevő nézetet kellett frissítenem.

Dinamikus csomópontok

Az „aktív rács” mellett a dinamikus csomópontok létrehozásának lehetősége a másik olyan képessége a PowerGUI-nak, ami lehetővé teszi egyszerű rendszergazda tevékenységek végrehajtására. A dinamikus csomópont olyan csomópontstruktúra, ami futásidőben jön létre. Ez ott hasznos, ahol nagyon sok objektumot kellene kezelni, például egy meghajtó teljes fájlkészletét. Ezt egy rácsban nagyin nehéz lenne megjeleníteni, viszont a fájlrendszer esetében a mappák eleve adják, hogy mappánként csoportosítjuk az objektumokat, ezt kezeléstechnikailag pedig a csomópontok automatikus (dinamikus) építésével lehet elérni.

A nehézség itt az, hogy a dinamikus csomópont az csomópont a javából, így ahhoz, hogy rá kattintva valami megjelenjen a rácsban, valami szkripttel is fel kell ruházni, azaz nem elég dinamikusan „legyártani” magukat a csomópontokat, a mögöttük található szkriptet is dinamikusan kell legenerálni.

Nézzünk egy nagyon egyszerű dinamikus csomópontot, ami csak annyit csinál, hogy legenerál 1-től 5-ig számokat, ezek lesznek a dinamikus csomópontok nevei, és az egyes csomópontok szkriptje az lesz, hogy a csomópont számának megfelelő darabszámú X-et ír ki a rácsba.

78 . ábra Az első dinamikus csomópontjaim

Ezen „csomópontgyár” szkriptjében használom a PowerGUI Local System csomagjában (PowerPack, lásd később) definiált Add-AdminConsoleDynamicNode megosztott függvényt, amivel az ilyen dinamikus csomópontokat le lehet generáltatni. Ahhoz, hogy ez a függvény látható legyen az én szkriptem számára, a More gomb megnyomása után feltáruló középső ablakrészben a PowerPack-ok közé fel kellett vennem a Local System csomagot is.

A függvényt meg lehet nézni a Shared Scripts legördülő menün keresztül, a definíciós része így néz ki:

function global:Add-AdminConsoleDynamicScriptNode {

     param(

          $ParentNode,

          [string] $Name,

          $Script,

          [System.Management.Automation.PSObject[]] $ScriptParameters = $null,

          [System.Management.Automation.PSObject] $AssociatedObject = $null,

          [System.Management.Automation.PSObject] $IconTypeIdentifier = $null,

          [switch]$PassThru

     )

Azaz meg kell adni neki, hogy melyik csomópont alá hozza létre a dinamikus csomópontot, mi legyen a neve a dinamikus csomópontnak, mi legyen a csomópont szkriptje, ha esetleg ennek a szkriptnek lennének paraméterei, akkor ezeket a következő paraméter gyanánt adhatjuk meg. Társíthatnánk még objektumhoz a kimenetet, bár ezt a lefutó szkript kimenete is meghatározhatja, és ikont is megadhatunk.

Nézzük, ennek az egyszerű dinamikus csomópontnak mi is a kinézete:

79 . ábra Egyszintű dinamikus csomópont

Látható, hogy szépen megszülettek a dinamikus csomópontok és működik a mögöttük található dinamikusan előállított szkript is. Itt tehát egy egyszintű struktúrát hoztam létre. Egy fokkal bonyolultabb eset, ha a dinamikus csomópontoknak generálodnak újabb dinamikus csomópontjuk! Ennek megvalósítása túlmutat a könyvünk keretein, de kihívást kedvelő olvasóimat arra bíztatom, hogy próbáljanak meg ilyet létrehozni.



Word To HTML Converter