Automating the world one-liner at a time…
Did your command or script fail and/or report an error? We hope to have a proper script debugger in a future version, but until then, MSH has some handy features to help you figure out what went wrong. In this series of blog entries, I will present some of those features. Thanks to Jim Truher [MSFT], Bruce Payette [MSFT], and Jeff Jones [MSFT] for their help in putting this together.
See the Windows "Monad" Shell Beta 2 Documentation Pack (http://www.microsoft.com/downloads/details.aspx?FamilyID=8a3c71d1-18e5-49d7-952a-c55d694ecee3&displaylang=en) for general information about Monad.
Part 1: http://blogs.msdn.com/monad/archive/2005/11/04/489138.aspx (Terminating vs. Non-Terminating Errors, ErrorRecord)Part 2: http://blogs.msdn.com/monad/archive/2005/11/08/490130.aspx ($error)Part 3: http://blogs.msdn.com/monad/archive/2005/11/09/490625.aspx (write-host)
Jon Newman [MSFT]
set-mshdebug [-Trace 0..2] [-Step] [-Off]
If your error is reproducible, you can turn on script tracing, or even get MSH to suspend and restart your script so that you can interactively look at the shell variables and the state of the world in the middle of your script. Look at this transcript:
MSH C:\temp> get-content .\test.msh$a = "line1"$a$a = "line2"$aMSH C:\temp> .\test.mshline1line2MSH C:\temp> set-mshdebug -trace 2MSH C:\temp> .\test.mshDEBUG: 1+ .\test.mshDEBUG: ! CALL script 'test.msh'DEBUG: 1+ $a = "line1"DEBUG: ! SET $a = 'line1'.DEBUG: 2+ $aline1DEBUG: 3+ $a = "line2"DEBUG: ! SET $a = 'line2'.DEBUG: 4+ $aline2MSH C:\temp>
"set-mshdebug -trace 2" turns on script tracing: level 0 is off, level 1 is line-by-line tracing, and level 2 also traces variable assignments, function calls, script invocation, and trap dispatches.
"set-mshdebug -Step" lets you step through your script one line at a time, almost as if it were in the debugger. You can use "No" or "No to All" to halt the script, or "Suspend" to suspend its operation temporarily. Notice how the prompt changes from ">" to ">>>". While the script is suspended, you can check the values of shell variables, or run entirely new commands or scripts, then return to the suspended script with "exit".
MSH C:\temp> set-mshdebug -StepMSH C:\temp> .\test.mshContinue with this operation?1+ .\test.msh[Y] Yes [A] Yes to All [H] Halt [S] Suspend [?] Help (default is "Y"): yDEBUG: 1+ .\test.mshContinue with this operation?1+ $a = "line1"[Y] Yes [A] Yes to All [H] Halt [S] Suspend [?] Help (default is "Y"): yDEBUG: 1+ $a = "line1"Continue with this operation?2+ $a[Y] Yes [A] Yes to All [H] Halt [S] Suspend [?] Help (default is "Y"): suspendMSH C:\temp>>> $aline1MSH C:\temp>>> exitContinue with this operation?2+ $a[Y] Yes [A] Yes to All [H] Halt [S] Suspend [?] Help (default is "Y"): yDEBUG: 2+ $aline1Continue with this operation?3+ $a = "line2"[Y] Yes [A] Yes to All [H] Halt [S] Suspend [?] Help (default is "Y"): hWriteDebug stopped because the DebugPreference was 'Stop'.At line:1 char:1+ . <<<< \test.mshMSH C:\temp>
Note that formatting scripts will also get the step-step treatment. You're most likely to see this when you get a non-terminating error:
MSH C:\temp> set-mshdebug -stepMSH C:\temp> get-content c:\nosuchfileContinue with this operation?1+ get-content c:\nosuchfile[Y] Yes [A] Yes to All [H] Halt [S] Suspend [?] Help (default is "Y"): yDEBUG: 1+ get-content c:\nosuchfileContinue with this operation?2+ if ($ErrorView -ne "CategoryView") {[Y] Yes [A] Yes to All [H] Halt [S] Suspend [?] Help (default is "Y"): yDEBUG: 2+ if ($ErrorView -ne "CategoryView") {Continue with this operation?3+ $myinv = $_.InvocationInfo[Y] Yes [A] Yes to All [H] Halt [S] Suspend [?] Help (default is "Y"): yDEBUG: 3+ $myinv = $_.InvocationInfo...
[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]
This is now Set-PSDebug, right? (I'm slow today, took me a while to wake up to this.)