Can I make a PowerShell $ error object behave in both script and interactive mode?

I am writing a PowerShell script that uses $error to detect and respond to errors. My problem is that I get different behavior for the $error object depending on how I run the script. If I run it interactively (in particular, from PowerShell ISE), then the errors are added to the collection, but if I run the same script from the command line, the same errors occur but are not added to the collection.

Here's the script (to illustrate the problem):

 # export_exception_test.ps1 # show me how many errors before we start "Count = " + $error.Count try { # treat non-terminating errors as terminating errors. $ErrorActionPreference = "Stop" # echo the setting to output $ErrorActionPreference # use sqlcmd to save the output of stored procedures to text files. # The first and third call will fail because the output folder does not exist. # The second call will succeed. 'first call to sqlcmd' sqlcmd -S myserver\myinstance -E -s `"`t`" -Q "EXEC mydatabase.dbo.FI_Codes" -b -o "B:\Exports_new\FI_Codes.txt" 'second call to sqlcmd' sqlcmd -S myserver\myinstance -E -s `"`t`" -Q "EXEC mydatabase.dbo.FI_Codes" -b -o "B:\Exports_newt\FI_Codes.txt" 'third call to sqlcmd' sqlcmd -S myserver\myinstance -E -s `"`t`" -Q "EXEC mydatabase.dbo.FI_Codes" -b -o "B:\Exports_new\FI_Codes.txt" # and a whole bunch more of these... # The error count should be two more than when we started. "Count = " + $error.Count # And this should be the most recent error message "Message = " + $error[0].Message } catch [Exception] { 'exception was caught!!!' "Count in catch clause = " + $error.Count $_.Exception.Message # the ultimate goal is to return a non-successful return code when the exports fail exit 1 } finally { # set this back to what it was $ErrorActionPreference = "Continue" # primitive trace output 'finally.' } 

When I run this from PowerShell ISE, it behaves as expected. SQLCMD causes an invalid error that is caught and processed. Here's the conclusion:

 PS U:\> C:\Users\etmatt\Documents\PowerShellScripts\export_exception_test.ps1 Count = 0 Stop first call to sqlcmd exception was caught!!! Count in catch clause = 1 Sqlcmd: Error: Error occurred while opening or operating on file B:\Exports_new\FI_Codes.txt (Reason: The system cannot find the path specified). finally. 

But when I run it from the command line, as in the case when I need to configure a scheduled task, nothing is added to $error , and there are no exceptions. Here's the conclusion:

 C:\Users\etmatt>powershell.exe -file "C:\Users\etmatt\Documents\PowerShellScripts\export_exception_test.ps1" Count = 0 Stop first call to sqlcmd Sqlcmd: Error: Error occurred while opening or operating on file B:\Exports_new\FI_Codes.txt (Reason: The system cannot find the path specified). second call to sqlcmd third call to sqlcmd Sqlcmd: Error: Error occurred while opening or operating on file B:\Exports_new\FI_Codes.txt (Reason: The system cannot find the path specified). Count = 0 Message = finally. C:\Users\etmatt> 

I also get the same results if I run the script file from the powershell command line and not cmd.exe (which makes sense). For instance:

 PS C:\> ."C:\Users\etmatt\Documents\PowerShellScripts\export_exception_test.ps1" 

I suspect that this has something to do with the execution context or maybe with the parser modes, which I still don't quite understand, or maybe even with my profile (although until now I started everything from one and the same PC under the same account). I have seen many examples on the Internet that use this basic try/catch approach with $ErrorActionPreference = "Stop" , so it seems to me that I can do this work.

So my question is essentially: can I make this script work, as I think it should? And if not, then what do I misunderstand? How to catch such errors? If this helps, I don't need super detailed exception handling for this, I just need to know when something goes wrong so that my task monitor can warn me. There is no nonzero return code from powershell.exe.

Am I learning to use $? and $LASTEXITCODE , but I'm sure $? will have the same problem as $error , and both only apply to the last statement executed, which is less than ideal, since my real script is quite long than this example.

EDIT:
Well, since then I found out that Windows executables (such as sqlcmd) never add anything to the $error collection, even if they return a non-zero exit code. $error is only used by cmdlets, if I understand correctly. I got a script $LASTEXITCODE , although I could use $? since it recognizes Windows exit executable codes and gets false for non-zero values.

To summarize, the script's behavior when launched from the command line is the correct, expected behavior. However, I do not know why I got different results from PowerShell ISE.

+4
source share
1 answer

For me, I invoke a command command using cmd /C <command> , and I have a similar problem. For $? zero return code $? is installed correctly, but there is no $error object (as powershell might seem, so this is normal), and the code behaves similarly in ISE, as well as when executing the command line.

My problem is that in cases where $ErrorActionPreference = "Stop" does not throw an exception. Probably because it does not have a $error object to throw. So now I need to check $? after each call to another script or program that is not neat. They should come up with a good solution for such a situation (perhaps by throwing a built-in exception that says about calling an external script / program)

0
source

All Articles