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.