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
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.