Powershell window disappears before I can read the error message
Asked Answered
B

12

52

When I call a Powershell script, how can I keep the called script from closing its command window. I'm getting an error and I'm sure I can fix it if I could just read the error.

I have a Powershell script that sends an email with attachment using the .NET classes. If I call the script directly by executing it from the command line or calling it from the Windows Scheduler then it works fine. If I call it from within another script (IronPython, if that matters) then it fails. All scenarios work fine on my development machine. (I really do have to get that "Works on My Machine" logo!) I've got the call to Powershell happening in a way that displays a command window and I can see a flicker of red just before it closes.

Sorry: Powershell 1.0, IronPython 1.1

Solution: powershell -noexit d:\script\foo.ps1

The -noexit switch worked fine. I just added it to the arguments I pass from IronPython. As I suspected, it's something that I can probably fix myself (execution policy, although I did temporarily set as unrestricted with no effect, so I guess I need to look deeper). I'll ask another question if I run into trouble with that.

Thanks to all for the help. I learned that I need to investigate powershell switches a little more closely, and I can see quite a few things that will prove useful in the future.

Burd answered 26/8, 2009 at 20:21 Comment(0)
R
65

Try with the -noexit switch:

powershell -noexit d:\script\foo.ps1
Reiser answered 27/8, 2009 at 12:9 Comment(3)
-noexit worked great. As I suspected, it's something I can probably figure out myself. If not, I'll be back.Burd
Criminy - can I send you a CHECK for this answer? This has been such a pain for us.Vitovitoria
For some reason window dissappear with NoExit switch. How could it be possible?Erg
O
31

You basically have 3 options to prevent the PowerShell Console window from closing, that I describe in more detail on my blog post.

  1. One-time Fix: Run your script from the PowerShell Console, or launch the PowerShell process using the -NoExit switch. e.g. PowerShell -NoExit "C:\SomeFolder\SomeScript.ps1"
  2. Per-script Fix: Add a prompt for input to the end of your script file. e.g. Read-Host -Prompt "Press Enter to exit"
  3. Global Fix: Change your registry key to always leave the PowerShell Console window open after the script finishes running.

Here are the registry keys to modify for 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\\\"\""

See my blog for more information and a .reg file that will apply these registry changes automatically.

Ogletree answered 7/7, 2014 at 22:32 Comment(2)
Upvoted for answering the question the best, but you should include those registry keys in your comment. "Always quote the most relevant part of an important link, in case the target site is unreachable or goes permanently offline."Homology
Good suggestion @lordcheeto. Done! :)Ogletree
M
7

I've needed this before and usually I didn't want to modify the script (typically for scripts fired off from the Task Scheduler). I just wanted to see what was spit out to console.

All you need to do is just append a Read-Host command after the script invocation e.g.:

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

BTW the problem with using Start-Transcript is that it doesn't capture EXE output. And any form of attempted logging in V1 and even V2 with the standard host will not capture the verbose, debug, progress or warning streams. You can only see these by viewing the associated host window.

One cheesy but effective way to capture all script output (stdout, stderr, verbose, warning, debug) is to use another host like cmd.exe e.g.:

cmd.exe /c powershell.exe "$pwd\foo.ps1" > foo.log
Milkfish answered 27/8, 2009 at 0:29 Comment(0)
S
5

I am generaly fine with scripts autoclosing except when an error occurs, where I need to see the error. Assuming you have not changed $ErrorActionPreference away from the default 'Continue', then for the behaviour I described do this at the end of you script

if ($Error)
{
    Pause
}
Spun answered 9/4, 2021 at 7:59 Comment(0)
S
2

There is no ordinary Try...Catch construction in Powershell; however you can trap exceptions instead and react properly. I.E:

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!";
}

You can also simulate Try...Catch construction:

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

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

Of course as soon as you will trap an exception, you can log it, sleep, or whatever you want with the error message. My examples just sleep, allowing you to read what happened, but it's much better to log all the errors. (The simplest way is to redirect them with >>).

Look also at: http://huddledmasses.org/trap-exception-in-powershell/

Saadi answered 27/8, 2009 at 7:54 Comment(0)
H
2

A quick and dirty solution is to use CTRL+S to halt the scrolling of the display and CTRL+Q to resume it.

Heraldic answered 11/6, 2014 at 13:22 Comment(0)
S
1

You have three options:

  • Do a catch in the script (if using Powershell V2)
  • Write a dummy script which catches and redirects stdout which you can then access as a variable from your IronPython script. VBS/Wscript Intro An addition to this is just liberally drop Read-Host commands everywhere, and hit return to page through.
  • Rather than outputting anything to the shell, wrap your powershell script in a second script that redirects all output to a log file.

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

Sectional answered 26/8, 2009 at 20:36 Comment(0)
F
1

Create run_ps_script.bat file containing

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

and make it default program to open PowerShell scrips.

Fidellas answered 30/1, 2013 at 3:4 Comment(0)
C
1

My solution was to execute the script with a command line from the console window instead of right-clicking the file -> execute with powershell.

The console keeps displaying the error messages, even though the execution of the script ended.

Combustion answered 9/11, 2015 at 11:6 Comment(0)
T
0

Have you thought about redirecting stdout and stderr to a file ex:

./ascript.ps1 >logs 2>&1

Note: You can create wrapper script in powershell that calls your powershell script with all necessary redirections.

Twinned answered 26/8, 2009 at 20:34 Comment(0)
V
0

My .PS1 script ran fine from the Powershell console but when "double-clicking" or "right-click open with powershell" it would exhibit the 'open/close' problem.

The Fix for me was to rename the script folder to a Name Without Spaces.

Then it all worked - Windows couldn't deal with "C:\This is my folder\myscript.ps1" but "C:\This_is_my_folder\myscript.ps1" worked just fine

Vaseline answered 24/5, 2021 at 18:40 Comment(1)
While a somewhat interesting cause of error: What does this do for I can see a flicker of red just before [the PowerShell] closes?Planchette
B
-1

A couple more ideas...You could use the start-sleep cmdlet at the end of you script to give you enough time to review the error.

You might also be able to use start-transcript to record the session to a text file.

Bustamante answered 26/8, 2009 at 21:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.