Függvényeink óvatos végrehajtása (-WhatIf)

Láthattuk korábban, hogy az olyan cmdletek esetében, amelyek valamilyen maradandó változást okoznak objektumokon, lehetőség van óvatos, „mi lenne ha” jellegű futtatásra a –WhatIf kapcsoló használatával. Ezt természetesen szintén le tudnánk programozni, de a fejlett függvények esetében ennek váza szintén rendelkezésünkre áll. Nézzünk egy olyan függvényt, ami a fájlok kiterjesztését nevezi át:

function rename-extention

{

     [cmdletbinding(

        ConfirmImpact = "Medium",

        SupportsShouldProcess = $true

    )]

 

    param(

    [Parameter(

        Mandatory = $true,

        Position = 1,

        ValueFromPipeline = $true,

        HelpMessage = "Átnevezendő fájl"

    )]

    [System.IO.FileInfo]

    [ValidatePattern('\w+\.\w+$')]

    $file,

 

    [Parameter(

        Mandatory = $true,

        Position = 0,

        HelpMessage = "Új kiterjesztés"

    )]

    [string]

    $extension

    )

 

    process {

        if ($PSCmdlet.ShouldProcess("$file" , "Kiterjesztés átnevezése $extension-re"))

        { Rename-Item -path $file.fullname -NewName ($file.basename + '.' + $extension)

        }

    }

}

Kezdjük először a paraméterezéssel! Ez már valószínű érthető az eddigiek alapján. Elsőként a $file paramétert definiálom kötelezőként, első pozícióba (valójában ez a 2., de a PowerShell 0-tól sorszámoz), csővezetékből is érkezhet a paraméter értéke és készítettem súgót is, valamint meghatároztam a típusát és a mintát (csak olyan fájlnevet fogadok el, amiben van kiterjesztés). Majd az új kiterjesztés megadását szolgáló $extension paramétert definiáltam első (0.) paraméterként, szintén értelemszerűen.

Nézzük most, hogy mi van a függvény elején:

    ConfirmImpact = "Medium",

    SupportsShouldProcess = $true

A SupportsShouldProcess  kapcsolja be a PowerShell azon „okosságát”, amellyel egyszerűen tudjuk megvalósítani a –whatif, -confirm és –verbose paramétereket, amelyeket megszokhattunk azon cmdleteknél, amelyek valami maradandó változást okoznak valamely provider objektumain. Ez még önmagában nem elég, a függvény tevékenységi részében is kell egy kis átalakítást végezni:

        if ($PSCmdlet.ShouldProcess("$file" , "Kiterjesztés átnevezése $extension-re"))

        { Rename-Item -path $file.fullname -NewName ($file.basename + '.' + $extension)

        }

Azaz a tényleges beavatkozást csak egy if vizsgálat után szabad elvégezni. Ebben a $PSCmdlet ShouldProcess metódusának igazra értékelése után hajtja csak végre a maradandó változásokat. Ez a metódus az, ami figyelembe veszi a –whatif, -confirm és –verbose switch paramétereket. Ha például van –whatif paraméter, akkor ez a metódus $false-ra értékelődik ki és nem csinálja meg az átnevezést, viszont kiírja, hogy mit csinálna. Ez a szöveg a ShouldProcess paramétereként átadott szövegekből tevődik össze:

[30] PS C:\> Get-Item C:\fájl.log | rename-extention txt -WhatIf

What if: Performing operation "Kiterjesztés átnevezése txt-re" on Target "C:\fá

jl.log".

Azaz az első paraméterként szereplő szöveget úgy érdemes kialakítani, hogy az utaljon a végrehajtandó művelet áldozatára (target), a második paraméter pedig a tevékenységre. Látható, hogy mindkettőben használhatok változókat, így részletes információkat nyerhetek a feldolgozásról, ami ugye a –whatif mellett csak teoretikus.

Majdnem ugyanez történik akkor is, ha a –verbose kapcsolót használom, csak éppen a ShouldProcess ilyenkor igazra értékelődik ki és így végre is hajtja az átnevezést:

[32] PS C:\> Get-Item C:\fájl.log | rename-extention txt -verbose

VERBOSE: Performing operation "Kiterjesztés átnevezése txt-re" on Target

"C:\fájl.log".

Azt, hogy mire értékelődjön ki a ShouldProcess elemenként mi magunk is szabályozhatjuk, ha a ‑confirm kapcsolót használjuk. Ilyenkor megjelenik az ismert, „bűvös” kérdés:

[33] PS C:\> Get-ChildItem C:\sokfájl | rename-extention log -Confirm

 

Confirm

Are you sure you want to perform this action?

Performing operation "Kiterjesztés átnevezése log-re" on Target "egy.txt".

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

 

Confirm

Are you sure you want to perform this action?

Performing operation "Rename File" on Target "Item: C:\sokfájl\egy.txt

Destination: C:\sokfájl\egy.log".

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

Hoppá! Egy fájlra vajon miért kétszer? Mert a függvényem –confirm kapcsolója átadódik a benne található Rename-Item cmdletnek is, jobban mondva az adott futtatási környezet $ConfirmPreference  változója billen át Low értékre. Azaz javítani kell a fejlett függvényemet, a Rename-Item résznél:

        { Rename-Item -path $file.fullname -NewName ($file.basename +

            '.' + $extension) -Confirm:$false}

Ekkor fájlonként már csak egyszer kapok jóváhagyás-kérést:

[37] PS C:\> Get-ChildItem C:\sokfájl | rename-extention txt -Confirm

 

Confirm

Are you sure you want to perform this action?

Performing operation "Kiterjesztés átnevezése txt-re" on Target "egy.log".

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

 

Confirm

Are you sure you want to perform this action?

Performing operation "Kiterjesztés átnevezése txt-re" on Target "hat.log".

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):y

 

Confirm

Are you sure you want to perform this action?

Performing operation "Kiterjesztés átnevezése txt-re" on Target "három.log".

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help

(default is "Y"):a

Megint csak rengeteg programozástól kímélt meg minket a PowerShell és mégis nagyon profi függvényt kaptunk.



Word To HTML Converter