Paraméterek

Természetesen a függvény1-nek nem sok értelme van, de például készítsünk egy olyan függvényt, ami kiszámítja egy kör területét. Nem egy konkrét körére gondolok, hanem olyan függvényt szeretnék, amibe paraméterként átadhatom az aktuális kör sugarát, és ebből számítja a területet:

[3] PS C:\> function körterület ($sugár)

>> {

>>     $sugár*$sugár*[math]::Pi

>> }

>> 

[4] PS C:\> körterület 12

452,38934211693

[5] PS C:\> körterület 1

3,14159265358979

Ez a formátum hasonlatos a hagyományos programnyelvek függvénydefinícióihoz, de a függvényem meghívásának módja kicsit más. Nem kell zárójelet használni, és ha több paraméterem lenne, azok közé nem kell vessző, mert ugye a PowerShellben a vessző a tömb elemeinek szétválasztására való!

Paraméterinicializálás

Nézzünk egy újabb függvényt, egy négyszög területét akarom kiszámoltatni:

[12] PS C:\> function négyszög ($x, $y)

>> { $x*$y }

>> 

[13] PS C:\> négyszög 5 6

30

Mi van akkor, ha egy négyzetnek a területét akarom kiszámoltatni, aminek nincs külön x és y oldala, csak x:

[14] PS C:\> négyszög 7

0

Hát ez nem sikerült, hiszen a függvényem két paramétert várt, az $y nem kapott értéket, így a szorzat értéke 0 lett. Lehetne persze a függvényen belül egy IF feltétellel megvizsgálni, hogy vajon a $y kapott-e értéket, és ha nem, akkor x2-et számolni. Ennél egyszerűbben is lehet ezt elérni a paraméterek inicializálásával:

[15] PS C:\> function négyszög ($x, $y = $x)

>> { $x*$y }

>> 

[16] PS C:\> négyszög 7

49

Itt a [15]-ös sorban az $y változónak átadom az $x értékét. Ez az értékadás azonban csak akkor jut érvényre, ha a függvény meghívásakor én nem adok neki külön értéket, azaz továbbra is működik a téglalap területének kiszámítása is:

[17] PS C:\> négyszög 8 9

72

Megjegyzés

Mi lenne, ha a négyszög függvény meghívására a hagyományos, zárójeles formátumot használnám most:

[22] PS C:\> négyszög(2,3)

Cannot convert "System.Object[]" to "System.Int32".

At line:2 char:6

+ { $x*$ <<<< y }

Meg is kaptam a hibát, hiszen a függvényem nincs felkészülve egy kételemű tömb területének kiszámítására.

A paramétereknek nem csak másik változó adhat alapértéket, hanem tehetünk oda egy konstanst is:

[18] PS C:\> function üdvözlet ($név = "Tibi")

>> { "Szia $név!" }

>> 

[19] PS C:\> üdvözlet Zsófi

Szia Zsófi!

[20] PS C:\> üdvözlet

Szia Tibi!

Típusos paraméterek

Hasonlóan, ahogy a változóknál is definiálhatunk típust, a függvények paramétereinél is jelezhetem, hogy milyen típusú adatot várok. Ez a függvény hibás működésének lehetőségét csökkentheti.

Nézzük a körterület-számoló függvényemet, mit tesz, ha szövegként adok be neki sugarat:

[33] PS C:\> körterület "2"

222222

Elég érdekesen alakul ez a geometria a PowerShellben! De eddigi ismereteink alapján rájöhetünk, hogy mi történt. Ugye a függvényünk belsejében ez található:

$sugár*$sugár*[math]::Pi

Az első $sugár a PowerShell szabályai szerint lehet „2” (szövegként). A második már nem, viszont működik az automatikus típuskonverzió, tehát csinál belőle 2-t (szám). Idáig kapunk „22”-t, azaz az első sztringemet („2”) kétszer egymás mellett. Majd jön a PI, ugyan az nem egész, de itt is jön a típuskonverzió, lesz belőle 3, azaz immár a „22”-t rakja egymás mellé háromszor, így lesz belőle „222222”.

Na, ezt nem szeretnénk, ezért tegyük típusossá a sugarat:

[42] PS C:\> function körterület ([double] $sugár)

>> {

>>     $sugár*$sugár*[math]::Pi

>> }

>> 

[43] PS C:\> körterület "2"

12,5663706143592

Itt már helyes irányba tereltük a PowerShell típuskonverziós automatizmusát, rögtön a paraméterátadásnál konvertálja a szöveges 2-t számmá, innentől már nincs félreértés.

Megjegyzés

Az is helyes eredményt adott volna, ha felcseréltük volna a tényezők sorrendjét:

[math]::Pi *$sugár*$sugár

De elegánsabb és „hibatűrőbb”, ha inkább típusjelzőkkel látjuk el a paramétereket.

Hibajelzés

Az előző körterület függvényemnél, ha a paraméter nem konvertálható [double] típussá, akkor hibát kapunk, anélkül, hogy mi ezt leprogramoztuk volna:

[19] PS C:\> körterület "nagy"

körterület : Cannot process argument transformation on parameter 'sugár'. Cann

ot convert value "nagy" to type "System.Double". Error: "Input string was not

in a correct format."

At line:1 char:11

+ körterület <<<<  "nagy"

    + CategoryInfo          : InvalidData: (:) [körterület], ParameterBindin.

   ..mationException

    + FullyQualifiedErrorId : ParameterArgumentTransformationError,körterület

Viszont elképzelhető olyan paraméterérték is, ami bár nem okoz problémát közvetlenül se a típusos paraméternek, se a függvény belsejének, de mi mégis szeretnénk hibaként kezelni. A körterület példámnál tekintsük hibának, ha valaki negatív számot ad meg sugárnak. A fentihez hasonló formátumú (piros betűk) hibaüzenetet írattathatunk ki a throw  kulcsszó segítségével:

[22] PS C:\>function körterület ([double] $sugár)

>> {

>>     if ($sugár -lt 0)

>>         { throw "Pozitív számot kérek!" }

>>      $sugár*$sugár*[math]::Pi

>> }

>> 

[23] PS C:\>körterület -2

Pozitív számot kérek!

At line:4 char:17

+          { throw <<<<  "Pozitív számot kérek!" }

    + CategoryInfo          : OperationStopped: (Pozitív számot kérek!:String

   ) [], RuntimeException

    + FullyQualifiedErrorId : Pozitív számot kérek!

De nem csak ilyen esetben lehet szükség hibakezelésre, hanem akkor is, ha valaki nem ad meg paramétert. Egy paraméterkötelező vagy opcionális voltát majd a 2.5 Fejlett függvények – script cmdletek fejezetben, a fejlett függvények függvénydefiníciójában tudjuk majd igazán profi módon beállítani, de most itt egyszerűen a throw segítségével végezzük ezt el:

[29] PS C:\>function körterület ([double] $sugár = $(throw "kötelező paramét

er"))

>> {

>>     if ($sugár -lt 0)

>>         { throw "Pozitív számot kérek!" }

>>      $sugár*$sugár*[math]::Pi

>> }

>> 

[30] PS C:\>körterület

kötelező paraméter

At line:1 char:47

+ function körterület ([double] $sugár = $(throw <<<<  "kötelező paraméter"))

    + CategoryInfo          : OperationStopped: (kötelező paraméter:String) [

   ], RuntimeException

    + FullyQualifiedErrorId : kötelező paraméter

[31] PS C:\>körterület 5

78,5398163397448

Látszik, hogy már az értékadásnál használhatjuk a hibajelzést, mint alapértéket. Ha nem ad a felhasználó paraméterként értéket, akkor végrehajtódik a hibakezelés, viszont ha ad értéket, akkor természetesen erre nem kerül sor.

Változó számú paraméter

Előfordulhat olyan is, hogy nem tudjuk előre, hogy hány paraméterünk lesz egy függvényben. Például szeretnénk kiszámolni tetszőleges darabszámú sztring hosszának az átlagát. Ilyenkor dilemmába kerülhetünk, hiszen hány paramétert soroljunk fel? Hogyan inicializáljuk ezeket?

Szerencsére nem kell ezen töprengenünk, mert a PowerShell készít automatikusan egy $args  nevű változót, amely tartalmazza a függvénynek átadott valamennyi olyan paramétert, amelyet úgy adunk át, hogy nem névvel hivatkozunk rájuk:

[25] PS C:\> function átlaghossz

>> {

>>     $hossz = 0

>>     if($args)

>>         {

>>             foreach($arg in $args)

>>                 {$hossz += $arg.length}

>>             $hossz = $hossz/$args.count

>>         }

>>     $hossz

>> }

>> 

[26] PS C:\> átlaghossz "Egy" "kettő" "három" "négy"

4,25

Az átlaghossz függvényemnek ezek alapján nincs explicit paramétere, azaz névvel nem is lehet hivatkozni a paramétereire, viszont implicit módon az $args tömbön keresztül természetesen megkapja mindazt a paramétert, amelyet átadunk neki. Ebben az esetben azonban nehezebben tudjuk kézben tartani a paraméterek típusát, ezt is majd a fejlett függvényekkel tudjuk elvégezni ( 2.5 Fejlett függvények – script cmdletek fejezet).

Mi van az $args változóval, ha vannak explicit paramétereink is? Nézzünk erre egy példát:

[46] PS C:\> function mondatgenerátor ($eleje, $vége)

>> {

>>     write-host $eleje, $args, $vége

>> }

>> 

[47] PS C:\> mondatgenerátor "Egy" "kettő" "három" "négy"

Egy három négy kettő

Láthatjuk, hogy úgy működik a PowerShell, ahogy vártuk, a nevesített paraméterek nem kerülnek bele az $args tömbbe, így a fenti függvényemben egyetlen argumentum sem lett duplán kiírva.

Hivatkozás paraméterekre

Eddig az összes függvénypéldámban a függvények meghívásakor a paraméterátadás pozíció alapján történt. Ez egyszerűen azt jelenti, hogy az első paraméter átadódik a függvénydefiníció paraméterei között felsorolt első változónak, a második paraméter a második változónak és így tovább. Ha több paramétert adunk át, mint amennyit a függvény definíciójában felsoroltunk, akkor ezek az extra paraméterek az $args változóba kerülnek bele.

Mi van akkor, ha egy függvénynek opcionális paramétere is van, és nem akarok neki értéket adni? Ezt eggyel több szóköz leütésével jelezzem? Alakítsuk át ennek szemléltetésére az előző „mondatgenerátor” függvényemet:

[48] PS C:\> function mondatgenerátor ($eleje, $közepe, $vége)

>> {

>>     write-host "Eleje: $eleje közepe: $közepe vége: $vége"

>> }

>> 

[49] PS C:\> mondatgenerátor egy kettő három

Eleje: egy közepe: kettő vége: három

[50] PS C:\> mondatgenerátor egy  három

Eleje: egy közepe: három vége:

Itt három explicit paramétert fogad a függvény. Ha tényleg három paraméterrel hívom meg, akkor minden paraméter a helye alapján kerül a megfelelő helyre. Ha a második paramétert ki szeretném hagyni, akkor ezt hiába akarom jelezni eggyel több szóközzel ([50]-es sor), ez természetesen a PowerShell parancsértelmezőjét nem hatja meg, így más módszerhez kell folyamodnom, ez pedig a név szerinti paraméterátadás:

[55] PS C:\> mondatgenerátor -eleje egy -vége három

Eleje: egy közepe:  vége: három

Így már tényleg minden a helyére került. A név szerinti paraméterátadásnál is számos gépelést segítő lehetőséget biztosít számunkra a PowerShell:

[56] PS C:\> mondatgenerátor -e egy  -v három

Eleje: egy közepe:  vége: három

[57] PS C:\> mondatgenerátor -e:egy  -v:három

Eleje: egy közepe:  vége: három

Az [56]-os sorban látható, hogy a nevekre olyan röviden elég hivatkozni, ami még egyértelművé teszi, hogy melyik paraméterre is gondolunk. Az [57]-es sorban meg az látható, hogy a PowerShell elfogadja a sok egyéb parancssori környezetben megszokott paraméterátadási szintaxist is, azaz hogy kettőspontot teszünk a paraméternév után.

A hely szerinti és pozíció szerinti paraméterhivatkozást vegyíthetjük is:

[58] PS C:\> mondatgenerátor -v: három egy -k: kettő

Eleje: egy közepe: kettő vége: három

Itt a szabály az, hogy a PowerShell először kiveszi a függvényhívásból a nevesített paramétereket, majd hely szerint feltölti a többi explicit paramétert, és ha még mindig marad paraméter, azt berakja az $args változóba.

Paraméterátadás változó szétpasszírozásával (splat operátor)

Nézzük, hogy hogyan lehet még paramétereket átadni. Vegyük példa gyanánt az előző mondatgenerátor függvényt. Egy változóban vannak tömbként az egyes paraméterek, vajon hogyan lehet a tömb elemeit átadni rendre az egyes paraméterek gyanánt?

[2] PS C:\> $v = "a", "b", "c"

[3] PS C:\> mondatgenerátor $v

Eleje: a b c közepe:  vége:

A [2]-es sorban látható a paramétereke tartalmazó tömböm, de ha ezt adom át a mondatgenerátoromnak, akkor nem azt kapom, amit szerettem volna. Az átadott változó mint egy egység adódott át az első, „eleje” paraméterként, és a többi paraméternek nem jutott érték.

A PowerShell 2.0-ban bevezettek egy új operátort, a „szétpasszírozás” operátorát (angolul splatting – szétfröccsenés) , amit pont arra találtak ki, hogy egy tömbváltozó elemeit adja át rendre a függvény vagy cmdlet paramétereiként:

[4] PS C:\> mondatgenerátor @v

Eleje: a közepe: b vége: c

Ez pont azt az eredményt adta, amit szerettem volna. Enélkül elég bonyolult lett volna ezt a fajta paraméterátadást megoldani.

Nézzük, hogy hogyan lehet név alapján átadni a paramétereket a szétpasszírozás operátorával. Ilyenkor a változóba hashtáblát kell tenni:

[7] PS C:\> $v = @{ közepe = "b"; vége = "c"; eleje = "a"}

[8] PS C:\> $v

 

Name                           Value

----                           -----

eleje                          a

közepe                         b

vége                           c

 

 

[9] PS C:\> mondatgenerátor @v

Eleje: a közepe: b vége: c

A fenti példában láthatjuk, hogy a paraméterek nem a sorrendjük, hanem a nevük alapján lettek átadva.

Kapcsoló paraméter ([switch])

Sok függvénynél előfordul olyan paraméter, amelynek csak két állapota van: szerepeltetjük a paramétert vagy sem. Ez nagyon hasonlít a [bool] adattípushoz, de feleslegesen sokat kellene gépelni, ha tényleg [bool]-t használnánk:

függvény -bekapcsolva $true

Sokkal egyszerűbb lenne csak ennyit írni:

függvény -bekapcsolva

Erre találták ki a [switch]  adattípust, amelyet elsődlegesen pont ilyen paraméterek esetében használunk.

[60] PS C:\> function lámpa ([switch] $bekapcsolva)

>> {

>>     if($bekapcsolva) {"Világos van!"}

>>     else {"Sötét van!"}

>> }

>> 

[61] PS C:\> lámpa

Sötét van!

[62] PS C:\> lámpa -b

Világos van!

A fenti „lámpa” függvényemet, ha kapcsoló nélkül használom, akkor „sötétet” jelez (az IF ELSE ága), ha van kapcsoló, akkor „világos”. Azaz, ha szerepel a paraméterek között a kapcsoló, akkor változójának értéke $true lesz, ha nem szerepel a kapcsoló, akkor változójának értéke $false lesz.

Megjegyzés

Korábban volt arról szó, hogy a paraméterek név szerinti hivatkozása mellett akár lehet szóközzel, akár kettősponttal értéket adni. Ez a [switch] paramétertípusnál nem mindegy:

[63] PS C:\old> lámpa -b $false

Világos van!

[64] PS C:\old> lámpa -b:$false

Sötét van!

A [63]-as sorban szóközzel választottam el a paramétertől az értéket, ezt a függvényem figyelmen kívül hagyta és a kapcsolónak $true értéket adott. A [64]-es sorban kettősponttal adtam a paraméternek értéket, itt már az elvárt módon $false értéket vett fel a kapcsolóm.

Paraméter-definíció a függvénytörzsben (param)

Ha valaki olyan programozói háttérrel rendelkezik, ahol megszokta, hogy a függvénydefinícióknál van egy külön deklarációs rész, akkor használhatják a param  kulcsszót a függvény paramétereinek deklarálásához:

[2] PS I:\>function get-random

>> {

>>     param ([double] $max = 1)

>>     $rnd = new-object random

>>     $rnd.NextDouble()*$max

>> }

>> 

[3] PS I:\>get-random 1000

315,589330306085

Itt a get-random függvényem neve után nem szerepel semmilyen paraméter, hanem beköltöztettem a függvénytörzsbe, itt viszont kötelezően egy param kulcsszóval kell jelezni a paramétereket. Ez akkor is hasznos lehet, ha bonyolultabb kifejezésekkel adok kezdőértéket a paramétereimnek, mert ezzel a külön deklarációs résszel sokkal olvashatóbb lesz a függvényem.

Ennek paraméterezési lehetőségnek egyébként nem is itt, hanem majd a szrkipteknél lesz még inkább jelentősége.

Paraméterek, változók ellenőrzése (validálás)

Természetesen a paraméterek ellenőrzése akkor a legegyszerűbb, ha eleve csak a kívánalmainknak megfelelő értékeket lehetne átadni. A típus megfelelőségének vizsgálatához már láthattuk, egyszerűen csak egy típusjelölőt kell a paraméter neve előtt szerepeltetni. De vajon milyen lehetőségünk van, ha még további megszorításokat szeretnénk tenni?

Ennek egyik lehetősége, hogy a függvényünk törzsében saját programkóddal ellenőrizzük az érték helyességét. Például nézzünk a korábban már látott körterület kiszámító függvényt:

[22] PS C:\>function körterület ([double] $sugár)

>> {

>>     if ($sugár -lt 0)

>>         { throw "Pozitív számot kérek!" }

>>      $sugár*$sugár*[math]::Pi

>> }

>> 

Itt én ellenőrzöm, hogy csak pozitív számot lehessen megadni sugárnak. A .NET keretrendszerben azonban vannak kifejezetten ilyen jellegű, paraméterellenőrzésre szolgáló osztályok is. Ilyen szabályokat hozzá is rendelhetünk változókhoz, erre szolgál a változók tulajdonságai között az Attributes tulajdonság:

[1] PS C:\> $a = 1

[2] PS C:\> Get-Variable a | fl

 

 

Name        : a

Description :

Value       : 1

Options     : None

Attributes  : {}

Alaphelyzetben ez a tulajdonság üres, vajon hogyan és mivel lehet feltölteni? Nézzük meg, hogy milyen metódusai vannak ennek az attribútumnak:

[8] PS C:\> ,(Get-Variable a).Attributes | gm

 

 

   TypeName: System.Management.Automation.PSVariableAttributeCollection

 

Name          MemberType            Definition

----          ----------            ----------

Add           Method                System.Void Add(Attribute item)

Clear         Method                System.Void Clear()

Contains      Method                System.Boolean Contains(Attribute item)

CopyTo        Method                System.Void CopyTo(Attribute[] array...

Equals        Method                System.Boolean Equals(Object obj)

GetEnumerator Method                System.Collections.Generic.IEnumerat...

GetHashCode   Method                System.Int32 GetHashCode()

GetType       Method                System.Type GetType()

get_Count     Method                System.Int32 get_Count()

get_Item      Method                System.Attribute get_Item(Int32 index)

IndexOf       Method                System.Int32 IndexOf(Attribute item)

Insert        Method                System.Void Insert(Int32 index, Attr...

Remove        Method                System.Boolean Remove(Attribute item)

RemoveAt      Method                System.Void RemoveAt(Int32 index)

set_Item      Method                System.Void set_Item(Int32 index, At...

ToString      Method                System.String ToString()

Item          ParameterizedProperty System.Attribute Item(Int32 index) {...

Count         Property              System.Int32 Count {get;}

Tehát van neki Add metódusa, ezzel lehet ellenőrzési objektumokat hozzáadni ehhez az attribútumhoz. A PowerShell MSDN weboldalán:

( http://msdn.microsoft.com/en‑us/library/system.management.automation.validateargumentsattribute(VS.85).aspx) )

  És a Reflector programmal a System.Management.Automation névtérbe beásva ezeket az ellenőrzési osztályokat lehet megtalálni:

Osztály neve

Felhasználási terület

System.Management.Automation.ValidateArgumentsAttribute

Szülő osztály

System.Management.Automation.ValidateCountAttribute

Attribútumok számának ellenőrzése

System.Management.Automation.ValidateEnumeratedArgumentsAttribute

Szülő osztály

System.Management.Automation.ValidateLengthAttribute

Hossz ellenőrzése (pl.: sztring, tömb)

System.Management.Automation.ValidatePatternAttribute

Regex minta ellenőrzése (sztring)

System.Management.Automation.ValidateRangeAttribute

Értéktartomány ellenőrzése (pl.: int, double)

System.Management.Automation.ValidateSetAttribute

Értéklista ellenőrzése (sztring)

System.Management.Automation.ValidateNotNullAttribute

Nem null érték ellenőrzése

System.Management.Automation.ValidateNotNullOrEmptyAttribute

Nem null és nem üresség ellenőrzése

Nézzünk ezek használatára néhány példát. Az elsőben szeretnék olyan változót használni, amely csak 1 és 5 darab karakter közötti hosszúságú szöveget fogad el:

[87] PS C:\old>$vl = New-Object System.Management.Automation.ValidateLengthA

ttribute 1,5

[88] PS C:\old>$szó = "rövid"

[89] PS C:\old>(get-variable szo).attributes.add($vl)

[90] PS C:\old>$szó="nagyonhosszú"

Cannot validate because of invalid value (nagyonhosszú) for variable szo.

At line:1 char:5

+ $szo= <<<< "nagyonhosszú"

A [87]-es sorban definiálom a VaildateLengthAttribute osztály egy objektumát. Majd létrehozok egy $szó nevű változót „rövid” tartalommal. Ennek a változónak az Attributes tulajdonságához hozzáadom az előbb létrehozott ellenőrzési objektumot. A [90]-es sorban a változómnak egy 5 karakternél hosszabb értéket szeretnék adni, de erre hibát kaptam.

Nézzünk egy hasonló példát az üresség vizsgálatára:

[94] PS C:\old>$s2="valami"

[95] PS C:\old>$vnne = New-Object System.Management.Automation.ValidateNotNu

llOrEmptyAttribute

[96] PS C:\old>(get-variable s2).Attributes.add($vnne)

[97] PS C:\old>$s2=""

Cannot validate because of invalid value () for variable s2.

At line:1 char:4

+ $s2= <<<< ""

Ha egy ilyen ellenőrzési attribútummal látunk el egy változót, akkor az megmutatkozik a változó tulajdonságai között is:

[98] PS C:\old>Get-Variable s2 | fl *

 

 

Name        : s2

Description :

Value       : valami

Options     : None

Attributes  : {System.Management.Automation.ValidateNotNullOrEmptyAttribute

              }

Ezekből az ellenőrzési objektumokból egyszerre többet is lehet egy változóhoz rendelni.

Sajnos ezen ellenőrzési objektumok felhasználásának egyik fő nehézsége az, hogy ahhoz, hogy ilyen szabályt egy változóhoz rendelhessük, ahhoz addigra már a változónak olyan értékkel kell rendelkeznie, amelyre teljesül az ellenőrzési feltétel. Azaz, ha például egy NotNull típusú ellenőrzést szeretnénk hozzárendelni egy változóhoz, addigra már valamilyen értékkel kell rendelkeznie a változónak, különben nem engedi a szabályt hozzárendelni. Így a függvények paramétereinél történő felhasználásuk kicsit körülményes:

[9] PS C:\> function nemnull ($p)

>> {

>>     $pteszt = 1

>>     $vnn = New-Object System.Management.Automation.ValidateNotNullAttribu

te

>>     (Get-Variable pteszt).Attributes.Add($vnn)

>> 

>>     $pteszt = $p

>> }

>> 

[10] PS C:\> nemnull 100

[11] PS C:\> nemnull

Cannot validate because of invalid value () for variable pteszt.

At line:6 char:12

+     $pteszt  <<<< = $p

Azaz a függvény törzsében létrehozok egy tesztelési célokat szolgáló $pteszt változót, ami kielégíti azt a feltételt, hogy nem üres az értéke, és ez a változó hordozza az ellenőrzési objektumot is. A függvény paraméterének ellenőrzésére a $p változó értékét átadom ennek a tesztelési célra létrehozott változónak. Amikor a függvényemet paraméter nélkül hívtam meg, akkor hibát kaptam. Itt igazából csak annyit spóroltam, hogy nem nekem kell lekezelni és kiírni a hibát, ezt a PowerShell helyettem elvégezte.

Az igazi, profi paraméterellenőrzést a PowerShell 2.0 a fejlett függvényeknél már lehetővé teszi, erről a 2.5   Fejlett függvények – script cmdletek fejezetben lesz szó.



Word To HTML Converter