Minden, amit tudni akartál a ShouldProcessEverything you wanted to know about ShouldProcess

A PowerShell-függvények számos funkcióval rendelkeznek, amelyek nagy mértékben javítják a felhasználók interakcióját.PowerShell functions have several features that greatly improve the way users interact with them. Az egyik fontos funkció, amely gyakran megtekinthető -WhatIf és -Confirm támogatott, és könnyen hozzáadható a funkcióihoz.One important feature that is often overlooked is -WhatIf and -Confirm support and it's easy to add to your functions. Ebben a cikkben részletesen ismertetjük a funkció megvalósításának lépéseit.In this article, we dive deep into how to implement this feature.

Megjegyzés

A cikk [eredeti verziója][] a által írt blogon jelent meg @KevinMarquette .The original version of this article appeared on the blog written by @KevinMarquette. A PowerShell-csapat köszönetet Kevin, hogy ossza meg velünk a tartalmat.The PowerShell team thanks Kevin for sharing this content with us. Tekintse meg a blogját a következő címen: PowerShellExplained.com.Please check out his blog at PowerShellExplained.com.

Ez egy egyszerű funkció, amely lehetővé teszi a függvények számára, hogy biztonsági hálót biztosítson azon felhasználók számára, akiknek szükségük van rá.This is a simple feature you can enable in your functions to provide a safety net for the users that need it. Semmi nem félelmetes, mint egy olyan parancs futtatása, amelyről tudja, hogy az első alkalommal veszélyes lehet.There's nothing scarier than running a command that you know can be dangerous for the first time. A futtatásának lehetősége -WhatIf nagy különbséget tehet.The option to run it with -WhatIf can make a big difference.

CommonParametersCommonParameters

Mielőtt megvizsgáljuk a [közös paraméterek][]megvalósítását, gyors áttekintést szeretnénk készíteni a használatáról.Before we look at implementing these common parameters, I want to take a quick look at how they're used.

A-WhatIf használataUsing -WhatIf

Ha egy parancs támogatja a -WhatIf paramétert, lehetővé teszi, hogy megtekintse a parancs végrehajtását a módosítások végrehajtása helyett.When a command supports the -WhatIf parameter, it allows you to see what the command would have done instead of making changes. Ez egy jó módszer a parancsok hatásának tesztelésére, különösen mielőtt elvégzi a roncsolást.it's a good way to test out the impact of a command, especially before you do something destructive.

PS C:\temp> Remove-Item -Path .\myfile1.txt -WhatIf
What if: Performing the operation "Remove File" on target "C:\Temp\myfile1.txt".

Ha a parancs helyesen implementálja ShouldProcess , az összes végrehajtott módosítást meg kell jelenítenie.If the command correctly implements ShouldProcess, it should show you all the changes that it would have made. Az alábbi példa egy helyettesítő karaktert használ több fájl törléséhez.Here is an example using a wildcard to delete multiple files.

PS C:\temp> Remove-Item -Path * -WhatIf
What if: Performing the operation "Remove File" on target "C:\Temp\myfile1.txt".
What if: Performing the operation "Remove File" on target "C:\Temp\myfile2.txt".
What if: Performing the operation "Remove File" on target "C:\Temp\importantfile.txt".

Használat – megerősítésUsing -Confirm

Az által támogatott parancsok -WhatIf -Confirm .Commands that support -WhatIf also support -Confirm. Így a művelet végrehajtása előtt megerősítheti a műveletet.This gives you a chance confirm an action before performing it.

PS C:\temp> Remove-Item .\myfile1.txt -Confirm

Confirm
Are you sure you want to perform this action?
Performing the operation "Remove File" on target "C:\Temp\myfile1.txt".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):

Ebben az esetben több lehetőség is rendelkezésre áll, amelyek lehetővé teszik a folytatást, a módosítások kihagyását vagy a szkript leállítását.In this case, you have multiple options that allow you to continue, skip a change, or stop the script. A Súgó a következőhöz hasonló beállításokat ismerteti.The help prompt describes each of those options like this.

Y - Continue with only the next step of the operation.
A - Continue with all the steps of the operation.
N - Skip this operation and proceed with the next operation.
L - Skip this operation and all subsequent operations.
S - Pause the current pipeline and return to the command prompt. Type "exit" to resume the pipeline.
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):

HonosításLocalization

Ez a kérés a PowerShellben van honosítva, így a nyelv az operációs rendszer nyelvétől függően változik.This prompt is localized in PowerShell so the language changes based on the language of your operating system. Ez még egy dolog, amit a PowerShell kezel.This is one more thing that PowerShell manages for you.

Paraméterek váltásaSwitch parameters

Gyors időt is igénybe kell venni, ha egy értéket át kell adni egy switch paraméternek.Let's take quick moment to look at ways to pass a value to a switch parameter. Ennek a legfőbb oka, hogy ezt a lehetőséget arra hívja fel, hogy gyakran szeretne paramétereket átadni a meghívott függvények számára.The main reason I call this out is that you often want to pass parameter values to functions you call.

Az első módszer egy adott paraméter szintaxisa, amely az összes paraméterhez használható, de többnyire a kapcsolók paramétereinek megjelenítésére szolgál.The first approach is a specific parameter syntax that can be used for all parameters but you mostly see it used for switch parameters. Megad egy kettőspontot, amely egy értéket csatol a paraméterhez.You specify a colon to attach a value to the parameter.

Remove-Item -Path:* -WhatIf:$true

Ugyanezt megteheti egy változóval is.You can do the same with a variable.

$DoWhatIf = $true
Remove-Item -Path * -WhatIf:$DoWhatIf

A második módszer egy szórótábla használata az érték kiértékeléséhez.The second approach is to use a hashtable to splat the value.

$RemoveSplat = @{
    Path = '*'
    WhatIf = $true
}
Remove-Item @RemoveSplat

Ha még nem ismeri a szórótáblában vagy a paramétercsomagolás, van egy másik cikkem, amely a [szórótáblában kapcsolatos tudnivalókat][]tartalmazza.If you're new to hashtables or splatting, I have another article on that covers everything you wanted to know about hashtables.

HelpuriSupportsShouldProcess

Az engedélyezés és támogatás első lépéseként -WhatIf -Confirm meg kell adni a SupportsShouldProcess CmdletBinding függvényben.The first step to enable -WhatIf and -Confirm support is to specify SupportsShouldProcess in the CmdletBinding of your function.

function Test-ShouldProcess {
    [CmdletBinding(SupportsShouldProcess)]
    param()
    Remove-Item .\myfile1.txt
}

Ily módon megadhatjuk a SupportsShouldProcess függvényt a -WhatIf következővel: (vagy -Confirm ).By specifying SupportsShouldProcess in this way, we can now call our function with -WhatIf (or -Confirm).

PS> Test-ShouldProcess -WhatIf
What if: Performing the operation "Remove File" on target "C:\Temp\myfile1.txt".

Figyelje meg, hogy nem hozott létre egy nevű paramétert -WhatIf .Notice that I did not create a parameter called -WhatIf. A megadásával SupportsShouldProcess automatikusan létrejön a számunkra.Specifying SupportsShouldProcess automatically creates it for us. Ha a -WhatIf paramétert bekapcsoljuk, a rendszer Test-ShouldProcess néhány dolgot is végrehajt -WhatIf .When we specify the -WhatIf parameter on Test-ShouldProcess, some things we call also perform -WhatIf processing.

Megbízhatóság, de ellenőrzésTrust but verify

Itt is fennáll a veszélye annak, hogy minden hívás örökli az -WhatIf értékeket.There's some danger here trusting that everything you call inherits -WhatIf values. A többi példa esetében feltételezem, hogy nem működik, és nagyon explicit, ha más parancsokat hív meg.For the rest of the examples, I'm going to assume that it doesn't work and be very explicit when making calls to other commands. Azt javasoljuk, hogy tegye meg ugyanezt.I recommend that you do the same.

function Test-ShouldProcess {
    [CmdletBinding(SupportsShouldProcess)]
    param()
    Remove-Item .\myfile1.txt -WhatIf:$WhatIf
}

Sokkal később újra meglátogatom az árnyalatokat, amint jobban megértettük a játék összes részletét.I will revisit the nuances much later once you have a better understanding of all the pieces in play.

$PSCmdlet. ShouldProcess$PSCmdlet.ShouldProcess

A metódus, amely lehetővé teszi a megvalósítását SupportsShouldProcess $PSCmdlet.ShouldProcess .The method that allows you to implement SupportsShouldProcess is $PSCmdlet.ShouldProcess. Meghívja $PSCmdlet.ShouldProcess(...) , hogy érdemes-e valamilyen logikát feldolgozni, és a PowerShell gondoskodik a többiről.You call $PSCmdlet.ShouldProcess(...) to see if you should process some logic and PowerShell takes care of the rest. Kezdjük egy példával:Let's start with an example:

function Test-ShouldProcess {
    [CmdletBinding(SupportsShouldProcess)]
    param()

    $file = Get-ChildItem './myfile1.txt'
    if($PSCmdlet.ShouldProcess($file.Name)){
        $file.Delete()
    }
}

A $PSCmdlet.ShouldProcess($file.name) (és a paraméter) ellenőrzésének meghívása, -WhatIf -Confirm majd ennek megfelelően kezeli azt.The call to $PSCmdlet.ShouldProcess($file.name) checks for the -WhatIf (and -Confirm parameter) then handles it accordingly. A -WhatIf ShouldProcess változás és a visszatérés leírásának kimenete $false :The -WhatIf causes ShouldProcess to output a description of the change and return $false:

PS> Test-ShouldProcess -WhatIf
What if: Performing the operation "Test-ShouldProcess" on target "myfile1.txt".

A -Confirm szünetelteti a parancsfájl szüneteltetését, és a folytatáshoz felszólítást kér a felhasználótól.A call using -Confirm pauses the script and prompts the user with the option to continue. $trueHa a felhasználó van kiválasztva, akkor visszaadja Y .It returns $true if the user selected Y.

PS> Test-ShouldProcess -Confirm
Confirm
Are you sure you want to perform this action?
Performing the operation "Test-ShouldProcess" on target "myfile1.txt".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):

Az az egyik nagyszerű funkciója, $PSCmdlet.ShouldProcess hogy a részletes kimenetként is megduplázódik.An awesome feature of $PSCmdlet.ShouldProcess is that it doubles as verbose output. Ettől kezdve a megvalósítás során gyakran is függek ShouldProcess .I depend on this often when implementing ShouldProcess.

PS> Test-ShouldProcess -Verbose
VERBOSE: Performing the operation "Test-ShouldProcess" on target "myfile1.txt".

TúlterhelésekOverloads

Az $PSCmdlet.ShouldProcess üzenetkezelés testreszabásához különböző paraméterekkel rendelkező különböző túlterhelések tartoznak.There are a few different overloads for $PSCmdlet.ShouldProcess with different parameters for customizing the messaging. A fenti példában már láttuk az elsőt.We already saw the first one in the example above. Ismerkedjen meg közelebbről.Let's take a closer look at it.

function Test-ShouldProcess {
    [CmdletBinding(SupportsShouldProcess)]
    param()

    if($PSCmdlet.ShouldProcess('TARGET')){
        # ...
    }
}

Ez olyan kimenetet hoz létre, amely tartalmazza a függvény nevét és a célt (a paraméter értékét).This produces output that includes both the function name and the target (value of the parameter).

What if: Performing the operation "Test-ShouldProcess" on target "TARGET".

Egy második paraméter megadása, mivel a művelet a műveleti értéket használja a függvény neve helyett az üzenetben.Specifying a second parameter as the operation uses the operation value instead of the function name in the message.

## $PSCmdlet.ShouldProcess('TARGET','OPERATION')
What if: Performing the operation "OPERATION" on target "TARGET".

A következő lehetőség a három paraméter megadása az üzenet teljes testreszabásához.The next option is to specify three parameters to fully customize the message. Három paraméter használata esetén az első a teljes üzenet.When three parameters are used, the first one is the entire message. A második két paraméter továbbra is használatban van az -Confirm üzenet kimenetében.The second two parameters are still used in the -Confirm message output.

## $PSCmdlet.ShouldProcess('MESSAGE','TARGET','OPERATION')
What if: MESSAGE

Gyors paraméter leírásaQuick parameter reference

Arra az esetre, ha csak azért jött létre, hogy milyen paramétereket érdemes használni, itt egy rövid útmutató, amely bemutatja, hogy a paraméterek hogyan változtatják meg az üzenetet a különböző -WhatIf forgatókönyvekben.Just in case you came here only to figure out what parameters you should use, here is a quick reference showing how the parameters change the message in the different -WhatIf scenarios.

## $PSCmdlet.ShouldProcess('TARGET')
What if: Performing the operation "FUNCTION_NAME" on target "TARGET".

## $PSCmdlet.ShouldProcess('TARGET','OPERATION')
What if: Performing the operation "OPERATION" on target "TARGET".

## $PSCmdlet.ShouldProcess('MESSAGE','TARGET','OPERATION')
What if: MESSAGE

Általában két paraméterrel szeretném használni az egyet.I tend to use the one with two parameters.

ShouldProcessReasonShouldProcessReason

A negyedik túlterhelésünk a többinél fejlettebb.We have a fourth overload that's more advanced than the others. Ez lehetővé teszi, hogy megszerezze a ShouldProcess végrehajtás okát.It allows you to get the reason ShouldProcess was executed. Csak azért vagyok itt felvenni ezt a teljességet, mert csak azt tudjuk megkeresni, hogy van-e $WhatIf $true helyette.I'm only adding this here for completeness because we can just check if $WhatIf is $true instead.

$reason = ''
if($PSCmdlet.ShouldProcess('MESSAGE','TARGET','OPERATION',[ref]$reason)){
    Write-Output "Some Action"
}
$reason

A $reason változót a negyedik paraméterre kell átadni a (z) hivatkozási változóként [ref] .We have to pass the $reason variable into the fourth parameter as a reference variable with [ref]. ShouldProcess``$reasonaz értékkel vagy a értékkel töltődik fel None WhatIf .ShouldProcess populates $reason with the value None or WhatIf. Nem mondtam, hogy ez hasznos volt, és nem volt ok arra, hogy soha ne használjam.I didn't say this was useful and I have had no reason to ever use it.

Hová helyezhetiWhere to place it

A használatával ShouldProcess biztonságosabbá teheti a parancsfájlokat.You use ShouldProcess to make your scripts safer. Ezért akkor használja, ha a parancsfájlok módosítást végeznek.So you use it when your scripts are making changes. Azt szeretném, hogy a hívást a lehető legpontosabban helyezze $PSCmdlet.ShouldProcess el a változáshoz.I like to place the $PSCmdlet.ShouldProcess call as close to the change as possible.

## general logic and variable work
if ($PSCmdlet.ShouldProcess('TARGET','OPERATION')){
    # Change goes here
}

Ha egy elemek gyűjteményét dolgozom fel, azt minden elemnél meghívom.If I'm processing a collection of items, I call it for each item. Így a hívás a foreach hurokba kerül.So the call gets placed inside the foreach loop.

foreach ($node in $collection){
    # general logic and variable work
    if ($PSCmdlet.ShouldProcess($node,'OPERATION')){
        # Change goes here
    }
}

Az OK, amiért szorosan megkerülem ShouldProcess a változást, hogy a lehető legtöbbet szeretnék végrehajtani, ha meg -WhatIf van adva.The reason why I place ShouldProcess tightly around the change, is that I want as much code to execute as possible when -WhatIf is specified. Azt szeretném, hogy a beállítás és az érvényesítés szükség esetén fusson, így a felhasználó megtekintheti ezeket a hibákat.I want the setup and validation to run if possible so the user gets to see those errors.

Azt is szeretném használni, hogy a saját projektjeim ellenőrzése során felhasználom a felzaklató teszteket.I also like to use this in my Pester tests that validate my projects. Ha olyan logikai logikával rendelkezem, amely nehezen tud kigúnyolni a Pesten, sokszor betakarom a ShouldProcess teszteket, és meghívhatom azt a -WhatIf tesztek során.If I have a piece of logic that is hard to mock in pester, I can often wrap it in ShouldProcess and call it with -WhatIf in my tests. Hatékonyabban tesztelheti a kódokat, mint az egyiket sem.It's better to test some of your code than none of it.

$WhatIfPreference$WhatIfPreference

Az első előnyben részesített változó $WhatIfPreference .The first preference variable we have is $WhatIfPreference. Alapértelmezés szerint ez a beállítás $false .This is $false by default. Ha úgy állítja be, hogy $true a függvény a megadott módon fusson -WhatIf .If you set it to $true then your function executes as if you specified -WhatIf. Ha ezt a munkamenetben állítja be, minden parancs végrehajtja a -WhatIf végrehajtást.If you set this in your session, all commands perform -WhatIf execution.

Amikor meghívja a függvényt a alkalmazásban -WhatIf , az értéke a $WhatIfPreference $true függvény hatókörén belülre lesz beállítva.When you call a function with -WhatIf, the value of $WhatIfPreference gets set to $true inside the scope of your function.

ConfirmImpactConfirmImpact

A legtöbb példa erre a -WhatIf lehetőségre vonatkozik, de minden eddig is működik, -Confirm hogy rákérdezzen a felhasználóra.Most of my examples are for -WhatIf but everything so far also works with -Confirm to prompt the user. A függvényt beállíthatja magas értékre, ConfirmImpact és megkérdezi a felhasználót, hogy a hívása a következő volt: -Confirm .You can set the ConfirmImpact of the function to high and it prompts the user as if it was called with -Confirm.

function Test-ShouldProcess {
    [CmdletBinding(
        SupportsShouldProcess,
        ConfirmImpact = 'High'
    )]
    param()

    if ($PSCmdlet.ShouldProcess('TARGET')){
        Write-Output "Some Action"
    }
}

Ez a hívás a Test-ShouldProcess hatás miatt végrehajtja a -Confirm műveletet High .This call to Test-ShouldProcess is performing the -Confirm action because of the High impact.

PS> Test-ShouldProcess

Confirm
Are you sure you want to perform this action?
Performing the operation "Test-ShouldProcess" on target "TARGET".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): y
Some Action

A nyilvánvaló probléma, hogy most már nehezebb más parancsfájlokban használni a felhasználó megkérdezése nélkül.The obvious issue is that now it's harder to use in other scripts without prompting the user. Ebben az esetben a-t átadhatjuk, $false -Confirm hogy letiltsa a kérdést.In this case, we can pass a $false to -Confirm to suppress the prompt.

PS> Test-ShouldProcess -Confirm:$false
Some Action

Azt mutatjuk be, hogyan adhatok hozzá -Force támogatást egy későbbi szakaszban.I'll cover how to add -Force support in a later section.

$ConfirmPreference$ConfirmPreference

$ConfirmPreference a egy automatikus változó, amely azt szabályozza, hogy mikor ConfirmImpact kéri a végrehajtás megerősítését.$ConfirmPreference is an automatic variable that controls when ConfirmImpact asks you to confirm execution. Itt láthatók a és a lehetséges $ConfirmPreference értékei ConfirmImpact .Here are the possible values for both $ConfirmPreference and ConfirmImpact.

  • High
  • Medium
  • Low
  • None

Ezekkel az értékekkel különböző hatásokat adhat meg az egyes függvényekhez.With these values, you can specify different levels of impact for each function. Ha a $ConfirmPreference értéknél magasabb értéket adott meg ConfirmImpact , akkor a rendszer nem kéri a végrehajtás megerősítését.If you have $ConfirmPreference set to a value higher than ConfirmImpact, then you aren't prompted to confirm execution.

Alapértelmezés szerint a értéke $ConfirmPreference és a High értéke ConfirmImpact Medium .By default, $ConfirmPreference is set to High and ConfirmImpact is Medium. Ha azt szeretné, hogy a függvény automatikusan rákérdezzen a felhasználóra, állítsa be a következőt: ConfirmImpact High .If you want your function to automatically prompt the user, set your ConfirmImpact to High. Ellenkező esetben állítsa be, hogy a Medium roncsolása és használata, Low Ha a parancs mindig biztonságos, éles környezetben fut.Otherwise set it to Medium if its destructive and use Low if the command is always safe run in production. Ha a értékre állítja none , akkor sem kell megadnia, ha meg van -Confirm adva (de továbbra is -WhatIf támogatást biztosít).If you set it to none, it doesn't prompt even if -Confirm was specified (but it still gives you -WhatIf support).

Ha függvényt hív meg -Confirm , a beolvasott érték a $ConfirmPreference Low függvény hatókörén belülre lesz állítva.When calling a function with -Confirm, the value of $ConfirmPreference gets set to Low inside the scope of your function.

Beágyazott megerősítési kérések letiltásaSuppressing nested confirm prompts

A a $ConfirmPreference meghívott függvények segítségével is beolvashatja.The $ConfirmPreference can get picked up by functions that you call. Ez olyan forgatókönyveket hozhat létre, amelyekben megerősítési kérést ad hozzá, és a meghívott függvény a felhasználót is kéri.This can create scenarios where you add a confirm prompt and the function you call also prompts the user.

Mit kell tennem, hogy a megjelenő parancsokban Megadhatom a -Confirm:$false megjelenő utasításokat.What I tend to do is specify -Confirm:$false on the commands that I call when I have already handled the prompting.

function Test-ShouldProcess {
    [CmdletBinding(SupportsShouldProcess)]
    param()

    $file = Get-ChildItem './myfile1.txt'
    if($PSCmdlet.ShouldProcess($file.Name)){
        Remove-Item -Path $file.FullName -Confirm:$false
    }
}

Ez egy korábbi figyelmeztetésre mutat vissza: olyan árnyalatok vannak, amelyekkel a -WhatIf rendszer nem ad át függvénynek, és a -Confirm függvénynek való átadáskor.This brings us back to an earlier warning: There are nuances as to when -WhatIf is not passed to a function and when -Confirm passes to a function. Megígérem, hogy később visszatérek.I promise I'll get back to this later.

$PSCmdlet. ShouldContinue$PSCmdlet.ShouldContinue

Ha a által biztosítottnál több szabályozásra van szüksége ShouldProcess , a parancssort közvetlenül is aktiválhatja ShouldContinue .If you need more control than ShouldProcess provides, you can trigger the prompt directly with ShouldContinue. ShouldContinue a figyelmen kívül hagyja a, a, a és a parancsot, és a rendszer $ConfirmPreference ConfirmImpact minden egyes -Confirm $WhatIfPreference -WhatIf végrehajtáskor kéri.ShouldContinue ignores $ConfirmPreference, ConfirmImpact, -Confirm, $WhatIfPreference, and -WhatIf because it prompts every time it's executed.

Gyors áttekintéssel könnyedén összekeverhető ShouldProcess és ShouldContinue .At a quick glance, it's easy to confuse ShouldProcess and ShouldContinue. Általában emlékezni kell a használatára, ShouldProcess mert a paraméter neve SupportsShouldProcess a következő: CmdletBinding .I tend to remember to use ShouldProcess because the parameter is called SupportsShouldProcess in the CmdletBinding. ShouldProcessSzinte minden esetben érdemes használni.You should use ShouldProcess in almost every scenario. Ezért először is érintettem ezt a módszert.That is why I covered that method first.

Vessünk egy pillantást a ShouldContinue működésbe.Let's take a look at ShouldContinue in action.

function Test-ShouldContinue {
    [CmdletBinding()]
    param()

    if($PSCmdlet.ShouldContinue('TARGET','OPERATION')){
        Write-Output "Some Action"
    }
}

Így kevesebb lehetőség közül választhat.This provides us a simpler prompt with fewer options.

Test-ShouldContinue

Second
TARGET
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"):

A legnagyobb probléma az, ShouldContinue hogy a felhasználónak interaktívan kell futtatnia, mert mindig kéri a felhasználót.The biggest issue with ShouldContinue is that it requires the user to run it interactively because it always prompts the user. Mindig olyan eszközöket kell kiépítenie, amelyeket más parancsfájlok is használhatnak.You should always be building tools that can be used by other scripts. Ennek megvalósítása a következő: -Force .The way you do this is by implementing -Force. Később újra meglátogatom ezt a gondolatot.I'll revisit this idea later.

Igen – mindYes to all

Ezt a rendszer automatikusan kezeli, ShouldProcess de ennél valamivel több munkát kell végrehajtania ShouldContinue .This is automatically handled with ShouldProcess but we have to do a little more work for ShouldContinue. Van egy második módszer túlterhelése, amelyben néhány értéket át kell adni a logika szabályozására való hivatkozással.There's a second method overload where we have to pass in a few values by reference to control the logic.

function Test-ShouldContinue {
    [CmdletBinding()]
    param()

    $collection = 1..5
    $yesToAll = $false
    $noToAll = $false

    foreach($target in $collection) {

        $continue = $PSCmdlet.ShouldContinue(
                "TARGET_$target",
                'OPERATION',
                [ref]$yesToAll,
                [ref]$noToAll
            )

        if ($continue){
            Write-Output "Some Action [$target]"
        }
    }
}

Felvettem egy foreach hurkot és egy gyűjteményt, hogy a működés közben megjelenjen.I added a foreach loop and a collection to show it in action. Kihúztam a ShouldContinue hívást, if hogy könnyebben olvasható legyen.I pulled the ShouldContinue call out of the if statement to make it easier to read. Ha négy paraméterrel rendelkező metódust hív meg, egy kicsit csúnya, de megpróbáltam úgy megtisztítani, ahogy tudtam.Calling a method with four parameters starts to get a little ugly, but I tried to make it look as clean as I could.

Megvalósítás – kényszerítésImplementing -Force

ShouldProcess és ShouldContinue -Force különböző módokon kell megvalósítani.ShouldProcess and ShouldContinue need to implement -Force in different ways. A megvalósítások trükk az, hogy ShouldProcess mindig végre kell hajtani a végrehajtást, de ShouldContinue Ha meg van adva, a rendszer nem hajtja végre -Force .The trick to these implementations is that ShouldProcess should always get executed, but ShouldContinue should not get executed if -Force is specified.

ShouldProcess-ForceShouldProcess -Force

Ha beállítja a- ConfirmImpact t high , az első dolog, amit a felhasználók megpróbálnak letiltani -Force .If you set your ConfirmImpact to high, the first thing your users are going to try is to suppress it with -Force. Ez az első dolog, amit amúgy is csinálok.That's the first thing I do anyway.

Test-ShouldProcess -Force
Error: Test-ShouldProcess: A parameter cannot be found that matches parameter name 'force'.

Ha felidézi a ConfirmImpact szakaszt, valójában a következőképpen kell meghívnia:If you recall from the ConfirmImpact section, they actually need to call it like this:

Test-ShouldProcess -Confirm:$false

Nem mindenki rájön, hogy erre van szükség, és -Confirm:$false nem hagyja figyelmen kívül ShouldContinue .Not everyone realizes they need to do that and -Confirm:$false doesn't suppress ShouldContinue. Ezért meg kell valósítani a -Force felhasználók józan eszét.So we should implement -Force for the sanity of our users. Tekintse meg ezt a teljes példát:Take a look at this full example here:

function Test-ShouldProcess {
    [CmdletBinding(
        SupportsShouldProcess,
        ConfirmImpact = 'High'
    )]
    param(
        [Switch]$Force
    )

    if ($Force -and -not $Confirm){
        $ConfirmPreference = 'None'
    }

    if ($PSCmdlet.ShouldProcess('TARGET')){
        Write-Output "Some Action"
    }
}

Paraméterként hozzáadjuk a saját -Force kapcsolót, és a alkalmazásban való $Confirm hozzáadáskor elérhető automatikus paramétert használjuk SupportsShouldProcess CmdletBinding .We add our own -Force switch as a parameter and use the $Confirm automatic parameter that is available when adding SupportsShouldProcess in the CmdletBinding.

[CmdletBinding(
    SupportsShouldProcess,
    ConfirmImpact = 'High'
)]
param(
    [Switch]$Force
)

A logikára koncentrálva -Force itt talál:Focusing in on the -Force logic here:

if ($Force -and -not $Confirm){
    $ConfirmPreference = 'None'
}

Ha a felhasználó megadja -Force , a megerősítési kérést le szeretnénk tiltani, ha nem is adják meg -Confirm .If the user specifies -Force, we want to suppress the confirm prompt unless they also specify -Confirm. Ez lehetővé teszi, hogy a felhasználó kényszerítse a változást, de továbbra is erősítse a változást.This allows a user to force a change but still confirm the change. Ezután a helyi hatókörben állítjuk be, amelyben felvesszük a $ConfirmPreference hívást ShouldProcess .Then we set $ConfirmPreference in the local scope where our call to ShouldProcess discoverers it.

if ($PSCmdlet.ShouldProcess('TARGET')){
        Write-Output "Some Action"
    }

Ha valaki megadja a -Force és -WhatIf a beállítást, akkor -WhatIf a prioritást kell figyelembe vennie.If someone specifies both -Force and -WhatIf, then -WhatIf needs to take priority. Ez a módszer megőrzi a -WhatIf feldolgozást, mert ShouldProcess mindig végre lesz hajtva.This approach preserves -WhatIf processing because ShouldProcess always gets executed.

Ne vegyen fel az utasításban található értéket a következővel: $Force if ShouldProcess .Do not add a check for the $Force value inside the if statement with the ShouldProcess. Ez az adott forgatókönyv ellenes mintázata annak ellenére, hogy ez a következő szakaszban látható ShouldContinue .That is an anti-pattern for this specific scenario even though that's what I show you in the next section for ShouldContinue.

ShouldContinue-ForceShouldContinue -Force

Ez a helyes módszer a megvalósítására -Force ShouldContinue .This is the correct way to implement -Force with ShouldContinue.

function Test-ShouldContinue {
    [CmdletBinding()]
    param(
        [Switch]$Force
    )

    if($Force -or $PSCmdlet.ShouldContinue('TARGET','OPERATION')){
        Write-Output "Some Action"
    }
}

Ha a kezelőtől balra helyezi el az $Force -or operátort, a rendszer először kiértékeli.By placing the $Force to the left of the -or operator, it gets evaluated first. Ilyen módon írja le röviden az if utasítás végrehajtását.Writing it this way short circuits the execution of the if statement. Ha a $force értéke $true , akkor a ShouldContinue nem kerül végrehajtásra.If $force is $true, then the ShouldContinue is not executed.

PS> Test-ShouldContinue -Force
Some Action

Ebben a forgatókönyvben nem kell aggódnia, -Confirm -WhatIf mert a nem támogatja őket ShouldContinue .We don't have to worry about -Confirm or -WhatIf in this scenario because they're not supported by ShouldContinue. Ezért nem kell másképpen kezelni, mint a ShouldProcess .This is why it needs to be handled differently than ShouldProcess.

Hatókörrel kapcsolatos problémákScope issues

A és a használata a -WhatIf -Confirm függvények minden részén és minden meghívásakor.Using -WhatIf and -Confirm are supposed to apply to everything inside your functions and everything they call. Ezt úgy teheti meg, hogy a $WhatIfPreference $true $ConfirmPreference Low függvény helyi hatókörében beállítja vagy beállítja a értéket.They do this by setting $WhatIfPreference to $true or setting $ConfirmPreference to Low in the local scope of the function. Ha másik függvényt hív meg, a meghívja az ShouldProcess értékek használatát.When you call another function, calls to ShouldProcess use those values.

Ez a legtöbb esetben megfelelően működik.This actually works correctly most of the time. Ha meghívja a beépített parancsmagot vagy egy olyan függvényt, amely ugyanabban a hatókörben van, akkor működik.Anytime you call built-in cmdlet or a function in your same scope, it works. Akkor is működik, ha egy parancsfájlt vagy függvényt hív meg egy parancsfájl-modulban a-konzolról.It also works when you call a script or a function in a script module from the console.

Egy adott hely, ahol nem működik, ha egy parancsfájl vagy egy parancsfájl-modul egy másik parancsfájl-modulban hívja meg a függvényt.The one specific place where it doesn't work is when a script or a script module calls a function in another script module. Előfordulhat, hogy ez nem jelent problémát, mint a nagy probléma, de a PSGallery létrehozott vagy lekérdezett modulok többsége parancsfájl-modulok.This may not sound like a big problem, but most of the modules you create or pull from the PSGallery are script modules.

A fő probléma az, hogy a parancsfájl-modulok nem öröklik $WhatIfPreference a $ConfirmPreference (vagy több más) értékeit más parancsfájl-modulok függvényében.The core issue is that script modules do not inherit the values for $WhatIfPreference or $ConfirmPreference (and several others) when called from functions in other script modules.

Az általános szabályként való összefoglalásának legjobb módja az, hogy ez megfelelően működik a bináris modulok esetében, és soha nem bízik meg a parancsfájl-modulok működésében.The best way to summarize this as a general rule is that this works correctly for binary modules and never trust it to work for script modules. Ha nem biztos abban, hogy tesztelje, vagy csak azt feltételezi, hogy nem működik megfelelően.If you aren't sure, either test it or just assume it doesn't work correctly.

Úgy érzem, ez nagyon veszélyes, mert olyan forgatókönyveket hoz létre, -WhatIf amelyekben a támogatás több, egymástól eltérő módon működő modulhoz van hozzáadva, de nem működik megfelelően, ha meghívja egymást.I personally feel this is very dangerous because it creates scenarios where you add -WhatIf support to multiple modules that work correctly in isolation, but fail to work correctly when they call each other.

Rendelkezünk egy GitHub RFC-vel, hogy kijavítsa a problémát.We do have a GitHub RFC working to get this issue fixed. További részletekért lásd: végrehajtási beállítások propagálása a parancsfájl-modulok hatókörén kívül .See Propagate execution preferences beyond script module scope for more details.

Bezárás alattIn closing

Meg kell vizsgálnunk, hogyan kell használni ShouldProcess minden alkalommal, amikor használni szeretném.I have to look up how to use ShouldProcess every time I need to use it. Sok időt vett igénybe a megkülönböztetése ShouldProcess ShouldContinue .It took me a long time to distinguish ShouldProcess from ShouldContinue. Szinte mindig meg kell keresni a használandó paramétereket.I almost always need to look up what parameters to use. Ezért ne aggódjon, ha a rendszer időről időre megzavarodott marad.So don't worry if you still get confused from time to time. Ez a cikk akkor jelenik meg, ha szüksége van rá.This article will be here when you need it. Biztos vagyok benne, hogy gyakran Hivatkozom rá.I'm sure I will reference it often myself.

Ha tetszett ez a bejegyzés, ossza meg velünk gondolatait a Twitteren az alábbi hivatkozás használatával.If you liked this post, please share your thoughts with me on Twitter using the link below. Mindig olyan személyeket szeretnék meghallgatni, akik értéket szereznek a tartalomból.I always like hearing from people that get value from my content.