web-dev-qa-db-fra.com

La fenêtre PowerShell disparaît avant que je puisse lire le message d'erreur

Lorsque j'appelle un script Powershell, comment empêcher le script appelé de fermer sa fenêtre de commande. Je reçois une erreur et je suis sûr que je peux la corriger si je pouvais simplement lire l'erreur.

J'ai un script Powershell qui envoie un e-mail avec pièce jointe en utilisant les classes .NET. Si j'appelle le script directement en l'exécutant à partir de la ligne de commande ou en l'appelant à partir du planificateur Windows, cela fonctionne très bien. Si je l'appelle à partir d'un autre script (IronPython, si cela importe), cela échoue. Tous les scénarios fonctionnent bien sur ma machine de développement. (Je dois vraiment obtenir le logo "Works on My Machine"!) J'ai reçu l'appel à Powershell d'une manière qui affiche une fenêtre de commande et je peux voir un scintillement de rouge juste avant sa fermeture.

Désolé: Powershell 1.0, IronPython 1.1

Lösung: powershell -noexit d:\script\foo.ps1

Le commutateur -noexit a bien fonctionné. Je viens de l'ajouter aux arguments que je passe d'IronPython. Comme je le soupçonnais, c'est quelque chose que je peux probablement résoudre moi-même (politique d'exécution, bien que je l'ai temporairement définie comme sans restriction sans effet, donc je suppose que je dois regarder plus en profondeur). Je poserai une autre question si j'ai des problèmes avec ça.

Merci à tous pour l'aide. J'ai appris que je devais étudier de plus près les commutateurs PowerShell, et je peux voir un certain nombre de choses qui se révéleront utiles à l'avenir.

27
jadero

Essayez avec le -noexit commutateur:

powershell -noexit d:\script\foo.ps1
45
Shay Levy

Vous avez essentiellement 3 options pour empêcher la fermeture de la fenêtre de la console PowerShell, que je décris plus en détail sur mon article de blog .

  1. Correctif unique: Exécutez votre script à partir de la console PowerShell ou lancez le processus PowerShell à l'aide du commutateur -NoExit. par exemple. PowerShell -NoExit "C:\SomeFolder\SomeScript.ps1"
  2. Correction par script: Ajoutez une invite de saisie à la fin de votre fichier de script. par exemple. Read-Host -Prompt "Press Enter to exit"
  3. Correctif global: Modifiez votre clé de registre pour toujours laisser la fenêtre de la console PowerShell ouverte une fois le script terminé.

Voici les clés de registre à modifier pour l'option # 3:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Applications\powershell.exe\Shell\open\command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit \"& \\\"%1\\\"\""

[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\0\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -NoExit \"-Command\" \"if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & \\\"%1\\\"\""

Voir mon blog pour plus d'informations et un fichier .reg qui appliquera automatiquement ces modifications de registre.

22
deadlydog

J'en avais besoin auparavant et je ne voulais généralement pas modifier le script (généralement pour les scripts lancés depuis le Planificateur de tâches). Je voulais juste voir ce qui était craché sur la console.

Tout ce que vous devez faire est simplement d'ajouter une commande Read-Host après l'invocation du script, par exemple:

PowerShell.exe -command { .\foo.ps1; read-Host "Press enter key to continue" }

BTW le problème avec l'utilisation de Start-Transcript est qu'il ne capture pas la sortie EXE. Et toute forme de tentative de connexion dans V1 et même V2 avec l'hôte standard ne capturera pas les flux verbeux, de débogage, de progression ou d'avertissement. Vous ne pouvez les voir qu'en affichant la fenêtre Host associée.

Un moyen ringard mais efficace pour capturer tous la sortie du script (stdout, stderr, verbose, warning, debug) est d'utiliser un autre hôte comme cmd.exe, par exemple:

cmd.exe /c powershell.exe "$pwd\foo.ps1" > foo.log
6
Keith Hill

Il n'y a pas de construction Try ... Catch ordinaire à Powershell; cependant, vous pouvez intercepter les exceptions à la place et réagir correctement. C'EST À DIRE:

Function Example() {
   trap [Exception] { 
      write-Host "We have an error!"; 
      write-error $("ERROR: " + $_.Exception.Message); 
      sleep 30;
      break; 
   }

write-Host "Hello world!";
throw "Something very bad has happened!";
}

Vous pouvez également simuler la construction Try ... Catch:

Function Example2() {
 ${
   write-Host "Our try clause...";
   throw "...caused an exception! It hurts!";
 }

trap [Exception] {
  write-error $_.Exception.Message;
  sleep 30;
  continue;
}

Bien sûr, dès que vous intercepterez une exception, vous pouvez la journaliser, dormir ou tout ce que vous voulez avec le message d'erreur. Mes exemples dorment simplement, vous permettant de lire ce qui s'est passé, mais il est préférable de consigner toutes les erreurs. (Le moyen le plus simple est de les rediriger avec >>).

Regardez aussi: http://huddledmasses.org/trap-exception-in-powershell/

2
juckobee

Ma solution était de exécuter le script avec une ligne de commande à partir de la fenêtre de la console au lieu de cliquer avec le bouton droit sur le fichier -> exécuter avec powershell .

La console continue d'afficher les messages d'erreur, même si l'exécution du script est terminée.

1
Franz

Vous avez trois options:

  • Faites une capture dans le script (si vous utilisez Powershell V2 )
  • Écrivez un script factice qui attrape et redirige la sortie standard à laquelle vous pouvez ensuite accéder en tant que variable à partir de votre script IronPython. Intro VBS/Wscript Un ajout à cela est juste de supprimer généreusement Read-Host commandes partout, et appuyez sur Retour à la page.
  • Plutôt que de sortir quoi que ce soit vers le Shell, encapsulez votre script PowerShell dans un deuxième script qui redirige tout sortie vers un fichier journal .

    PS C:> myscript.ps1 | Out-File myscript.log

1
aronchick

Une solution rapide et sale est d'utiliser CTRL+S pour arrêter le défilement de l'affichage et CTRL+Q pour le reprendre.

1
Chris Oakey

Quelques idées supplémentaires ... Vous pouvez utiliser l'applet de commande start-sleep à la fin de votre script pour vous donner suffisamment de temps pour examiner l'erreur.

Vous pourriez également être en mesure d'utiliser start-transcript pour enregistrer la session dans un fichier texte.

0
Mike Pfeiffer

Créer run_ps_script.bat fichier contenant

@PowerShell.exe -command "try { %1 } finally { read-Host 'Press ENTER...' }"

et en faire un programme par défaut pour ouvrir les scripts PowerShell.

0
Konstantin Spirin

Avez-vous pensé à rediriger stdout et stderr vers un fichier ex:

./ascript.ps1> journaux 2> & 1

Remarque: Vous pouvez créer un script wrapper dans powershell qui appelle votre script powershell avec toutes les redirections nécessaires.

0
Piotr Czapla