2010-09-21 3 views
8

J'écris un script pour créer des machines virtuelles, et évidemment, je voudrais soutenir la sémantique standard confirment/whatif. Cependant, si j'ai un certain nombre de machines à créer, il serait bon que je puisse différencier entre "Oui" et "Oui à tous", donc je ne dois pas nécessairement reconfirmer chaque machine.

$ pscmdlet.ShouldProcess renvoie uniquement une valeur booléenne, alors comment puis-je faire la différence?

+0

je pouvais utiliser $ psCmdlet.ShouldContinue (string, légende, yesToAll, noToAll), mais cela ne prend pas en charge ConfirmImpact et whatif. – user103633

+0

Oh, et une autre chose - j'espérais utiliser oui vs oui à tous pour demander une confirmation supplémentaire si l'utilisateur semblait être cavalier sur la création de nombreuses machines virtuelles dans une situation de faible ressources. Je suppose que ce n'est pas faisable dans ce cas. – user103633

Répondre

9

Voici un exemple de fonction qui accepte l'entrée de pipeline pour le nom de l'ordinateur et met en œuvre le comportement que vous désirez:

function set-something { 
    [cmdletbinding(SupportsShouldProcess=$true)] 
    param(
     [parameter(position=0, valuefrompipeline=$true)] 
     $Computer, 
     [parameter(position=1)] 
     $Value 
    ) 

    process { 
     if ($pscmdlet.shouldprocess("Are you sure?")) {   
      write-host "setting machine $computer to $value" 
     } 
    } 
} 

"srv1","srv2","srv3" | set-something -value 42 -confirm 

Si vous répondez « oui », vous serez invité à la machine suivante. Si vous répondez «oui à tous», vous ne serez plus invité. La partie importante est que vous utilisez l'entrée de pipeline - cela provoque l'exécution de la fonction dans son ensemble seulement une fois, mais le bloc de processus dans la fonction est invoqué une fois pour chaque élément entrant dans le pipeline. Cela lui permet de se souvenir du "oui pour tous" et ne demandera pas d'invocations de bloc de processus ultérieures. Avoir du sens?

MISE À JOUR: il n'est pas nécessaire d'utiliser un pipeline pour que cela fonctionne. La chose importante est que la fonction doit être capable de garder l'état, donc passer toutes les entrées dans un tableau ou une collection en tant que paramètre fonctionnerait aussi. Dans ce cas, vous bouclez la collection $ computer vous-même. Avec un pipeline, effectivement les boucles de l'enveloppe pour vous.

+0

Je suis parfaitement clair sur la mise en œuvre, merci. Ce qui n'était pas clair pour moi dans les documents, c'est que cela devrait toujours être utilisé dans le contexte d'un pipeline. – user103633

+0

Le commentaire de pipeline ne concerne que mon exemple. Vous pouvez le faire sans pipeline aussi, où toute l'entrée est passée en argument. Mon point principal est que la fonction est invoquée une seule fois pour pouvoir garder l'état. – x0n

+3

J'ai un code dans lequel je ne pouvais pas mettre 'ShouldProcess' dans la boucle externe, mais je voulais le placer dans la fonction interne. J'ai donc passé '$ pscmdlet' à la fonction interne, et j'ai appelé' ShouldProcess' à la place. Ensuite, l'état est stocké dans le contexte de la boucle externe, et oui/non-tout fonctionne. – scobi