Existe-t-il un moyen de supprimer les invites interactives dans un script PowerShell?

13

Lors de l'écriture de scripts PowerShell, j'ai remarqué que lorsque certaines applets de commande rencontraient des problèmes, elles faisaient apparaître une invite interactive, Remove-Item sur un répertoire non vide en étant un exemple. C'est mortel lorsque vous essayez d'automatiser des tâches, je préférerais de beaucoup que l'action échoue et soit lance une exception, soit renvoie un mauvais code de retour afin que le script entier ne soit pas verrouillé en attendant une réponse.

Existe-t-il un moyen de forcer PowerShell à échouer automatiquement, au lieu de rechercher les commentaires des utilisateurs sur les actions?

Chuu
la source
Je pense que vous devriez renommer votre question "Comment puis-je faire Remove-Iteméchouer rapidement?"
Jay Bazuzi
1
Il ne s'agit pas spécifiquement de Remove-Item, c'est juste un exemple illustratif. Il existe de nombreuses autres applets de commande qui bloqueront l'attente de l'entrée utilisateur dans les bonnes conditions.
Chuu

Réponses:

5

La solution proposée par Eris démarre effectivement une autre instance PowerShell. Une autre façon de le faire, avec une syntaxe plus simple, consiste à décortiquer vers une autre instance de powershell.exe.

powershell.exe -NonInteractive -Command "Remove-Item 'D:\Temp\t'"
Damian Powell
la source
2
J'aime vraiment la solution, mais elle ramène des cauchemars d'écriture de procédures stockées fiables dans TSQL avant TRY / CATCH, ce qui obligeait à entourer littéralement chaque requête avec un passe-partout de détection d'erreurs.
Chuu
4

Voir Get-Help about_Preference_Variables:

$ ConfirmPreference
------------------
    Détermine si Windows PowerShell vous invite automatiquement à
    confirmation avant d'exécuter une applet de commande ou une fonction.

...

Aucun: Windows PowerShell ne demande pas automatiquement.
                         Pour demander la confirmation d'une commande particulière, utilisez
                         le paramètre Confirmer de l'applet de commande ou de la fonction.

Donc:

> $ConfirmPreference = 'None'
Jay Bazuzi
la source
J'ai trouvé cela pour voir le problème que je devais régler. $ ConfirmPreference = 'Low'
Guy Thomas
Cela ne semble pas fonctionner. Remove-Item sur un répertoire vous donne toujours une invite après avoir défini $ ConfirmPreference sur 'None' ou 'Low'
Chuu
Fonctionne pour Remove-ADUser(Server 2012R)
velkoon
2

Ok, c'est vraiment moche, mais les taches de moutarde sainte ça "marche".

Problèmes:

  • Je n'ai pas compris comment continuer après la première erreur
  • Dans ce cas, il supprime les fichiers simples, puis s'arrête au premier dossier
  • Je n'ai pas compris comment faire fonctionner cette applet de commande si j'ajoute le paramètre UseTransaction
  • Cela ne fonctionnera que pour le cas simple (commandes qui ne font pas beaucoup de choses avec l'environnement actuel). Je n'ai rien testé de complexe

    $MyPS = [Powershell]::Create()
    $MyPS.Commands.AddCommand("Remove-Item")
    $MyPS.Commands.AddParameter("Path", "D:\Temp\t")
    $MyPS.Invoke()

Production:

Commands                                                                                                                 
--------                                                                                                                 
{Remove-Item}                                                                                                            
{Remove-Item}                                                                                                            
Exception calling "Invoke" with "0" argument(s): "A command that prompts the user failed because the host program or the 
command type does not support user interaction. The host was attempting to request confirmation with the following 
message: The item at D:\Temp\t has children and the Recurse parameter was not specified. If you continue, all children 
will be removed with the item. Are you sure you want to continue?"
At line:19 char:1
+ $MyPS.Invoke()
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CmdletInvocationException
Eris
la source
La raison pour laquelle je n'ai pas marqué cela comme une solution est que je n'ai pas trouvé le temps de le tester. Quelqu'un a-t-il déployé ou testé ce code en plus de l'auteur?
Chuu
0

Toutes les solutions ci-dessus ont échoué pour moi lorsque j'ai créé un répertoire, ce qui signifie que j'ai été invité à OK chaque répertoire créé par mon script - ce qui était beaucoup. Ce qui a fonctionné pour moi, c'est d'apper | Out-null afin de diriger les résultats vers Out-Null

New-Item -ItemType Directory -Path $directory -Force:$true | Out-Null

Notez que $ Directory est une chaîne avec le chemin d'accès complet au répertoire que vous souhaitez créer. J'espère que cela fait gagner du temps à quelqu'un: P

Chris Sprague
la source
-1

Je propose deux techniques

a) Ajouter -force

b) Ajouter -errorAction silently continue

Voici comment je recherche les applets de commande qui prennent en charge un paramètre particulier

Get-Command | where { $_.parameters.keys -contains "erroraction"}
Guy Thomas
la source
L'une des raisons pour lesquelles j'ai commencé dans cette voie est que je veux généralement faire le contraire de -force, c'est-à-dire quelque chose comme -alwaysbackoff. J'ai trouvé que la plupart des commandes qui prennent en charge -force ne semblent pas avoir la possibilité de reculer.
Chuu
1
En passant, une abréviation pratique pour -errorAction SilentlyContinueest -ea 0.
Jay Bazuzi