edit: fixed error in command line example. Thanks to Aurélien Bonnin and FoW for pointing it out.
edit 2 : this version has been updated, please search the blog for the latest version.
When creating and configuring an LTI deployment solution there is one thing that always bugs me immensly: debugging custom scripts. Writing the scripts is easy, but debugging them is a whole different experience. The reason is simple, to debug a script you normally need to launch it from within the MDT environment (during the deployment). Consequently, it can be quite hard and very slow to iron out any errors that they (might) contain because of the need to run a full deployment of a computer, just to be able to do some testing.
This isn't the actual part that bugs me though. The annoying part is when the script fails and MDT ends, all because of a silly mistake made in the script; this for me is the frustrating part that could at times drive me insane. Because MDT has now terminated, pretty much the only sure way to re-test the script is to re-run the deployment; vastly slowing down the debugging time.
I should point out that this is no fault of MDT, it is all mine; after all, I was the one who put the error in the script! But, because of the way MDT works, the debugging of these custom scripts can be labourious task.... until now! [cue drum-roll] I would like to present version 0.1 of the "MDT Debugger"! This nifty little tool makes debugging most custom actions, script or not, simpler and prevents MDT from terminating with the red error screen if the custom action has failed.
The MDT Debugger sits in-between MDT and your custom script and intercepts the return code that is normally sent back to MDT from your custom action. It then displays the error code and allows you to either accept and return it to MDT, edit it before returning it to MDT, or to relaunch the custom action again. This later option gives you the opportunity to fix any errors in the script/action and then relaunch it - thus eliminating the need to relaunch the deployment process from the very beginning just to re-test the custom action.
As you can see in the above screenshot, my custom action (in this case, a VBS script) failed with a "File not found" error message. Because MDT by default expects an error code of either 0 or 3010, any process that returns a different error code will cause MDT to stop immediately with the error screen shown at the top of this post. However, you'll notice a new window in the top-left of the screenshot above.
But, with the MDT Debugger, the error code from my custom action is trapped and presented in the HTML window shown in the above screenshot. With this new window it is possible to manually edit the return code, overridding the one that was returned by the custom action, then return it to MDT (perhaps you don't want to do anything other than continue with the MDT task sequence without it failing). Or, the cause of the failure in the custom action can be fixed so that you can then immediately re-run it again. Each time you relaunch the action, you are returned to the MDT Debugger window afterwards where you can review the error code returned and decide the action you want to take. And, the best bit is that MDT will wait indefinetely until you decide on the error code that you want to return back to MDT.
To use the MDT Debugger, you need to follow the steps below:
There is one thing that I also need to mention. This tool will only work for LTI deployments, because of the fact that it requires showing on the desktop a screen that the user will interact with - something that ZTI deployments are not too fond of. Finally, I have tested this as much as possible and have used it in several projects. Please let me know if you find any problems with it, or have any suggestions for changes!
This post was contributed by Daniel Oxley, a Consultant with Microsoft Services Spain
This looks great Daniel - thanks for your hard work
I'm calling cscript with a .wsf file from my Run Command task step and I see the initial screen for the debugger appear, but I am still getting the error message with the 0x80004005, etc.
Here's the command line I am passing:
cscript.exe %scriptroot%\CUSTOM_MDTDebugger.wsf cscript.exe %scriptroot%\ZTIOEMLock.wsf
Would the fact that I'm running an WSF file make any difference?
Is it possible to use this to debug an application not installing correctly? Would I have to insert a line in to the MDT script that installs apps? I'm having an app return an error code of 1 to MDT, but it seems to install ok. Trying to figure out why it's returning that error code even though it seems to successfully complete installation for the app.
@ J. Garrett,
I don't think this is the problem as I have tried it myself with WSF scripts. At what point do you get that error?
If you want to manually test it, you can simply open CMD into the network share where the deployment share is and run the script manually, this will have the same effect as running it from the MDT Task Sequence.
No, this is not possible if you are using the Install Application action in the task sequence.
An error code of 1 may not be a problem, if you find my post about Robocopy exit codes on this blog you'll see my explination about non-zero error codes and what they might actually mean.
I am getting the error message at the exact same place where I would get the error if I wasn't calling my custom wsf through your debugging routine.
I am calling the custom action from the State Restore Section of my Client Task Script. I've added the Run Command Line task step in that part of the sequence right after the "Install Applications" step. Does it matter if I set the "Start In" directory to be "%scriptroot%"?
What is suprising then is that the debugger I wrote is not catching the error. Do you even see the HTML screen open? If so, what is the command line listed as the process at the top?
It is not normally necessary to set the "start in" folder if you specify the full path on the command line, such as "%scriptroot%\myscript.wsf.
this is a general error - you need to grep your BDD.log file and search a few lines above the error instance to find out whats caused it.
I notice that Dan has put conflicting info in the post. In the screen shot you will see no 2nd cscript.exe call however in the post text he includes it. Have you tried without the second cscript.exe call?
i.e. cscript.exe %scriptroot%\CUSTOM_MDTDebugger.wsf %scriptroot%\ZTIOEMLock.wsf
Yes, I do see your HTA's opening screen come up, but that is immediately followed by the error screen.
I didn't catch that little difference between the command invocations in the screen shot for the task sequence and where he actually spells it out.
I'm in the process of trying letting the .WSF file run so it's invoking CSCRIPT.EXE file it's extension definition. (typing in a path to a file ending in .WSF should invoke the default script engine, which should be CSCRIPT unless otherwise changed.) I'll let you all know if there's any difference when it comes up.
You're right it's necessary to use the command shown in the screen shot instead of the command explained in the text.
I've just tried the MDT Debugger on one of my custom script in MDT 2010 and it works fine if you use this syntaxe :
cscript.exe %SCRIPTROOT%\CUSTOM_MDTDebugger.wsf %SCRIPTROOT%\CUSTOM_MyCustomAction.vbs
But if you use put a 2nd cscript.exe in the command line step, the MDT debugger window appears but don't catch the error code and MDT end with errors.
@Aurelien, FoW & Joel
Sorry for the typo, and thanks for commenting about it. This has been amended in the blog text.
Thanks for the clarification and correction. I found 5 really dumb errors in my code really fast. Now if I can only get past this one last hard problem with my custom script...
At least the debugger's there to help me!
Thanks again for the cool tool!
great job for debugging.
However when debugging a script using parameters like Myscript.wsf /AParameter the debugger cannot run this command.
Commenting out line #47 solved the issue
I was getting really angry trying to debug a custom script for synching time on workstations. I could not get any useful error data out of the SMS logs. Thanks to this tool, I was able to get the output from the Windows Scripting Host, pinpointing the line of code that generated the error. The cause of the code failure? Curly braces pasted from the Internet... a classic blunder! However, without this tool I might never have spotted the problem. Thanks SO much. This tool should be an integral part of MDT(for 2010 Update 2?).
Hi, can i use this script to debug PowerShell script in mdt 2010 update 1 ?
I receive this error when I run the script in MDT and Windows XP. Active X component can't create object: 'InternetExplorer.application'. CustomMDTDebygger.wsf(90,3). Any solutions?