Inside a Task Sequence
I’ve done a few sessions now where I demonstrated how to put some hooks into a task sequence so that you can single step through the process and “poke around” to see exactly what is going on. Since I’ve promised to make those scripts available, and will get lots of e-mails from people if I don’t do that, I’ll provide those at the bottom of this blog posting.
But the scripts by themselves require some explanation, some instructions, and some caveats.
Some Explanation
First, let’s talk about the basic setup. If you look at a ConfigMgr task sequence, it contains a number of steps and groups that define the sequential process that is going to be executed. This is actually converted into XML, where each step and group becomes a series of XML entries that define:
- The command line to be executed.
- The variables that are expected by the step (at least those that can be configured by the task sequence editor – the step’s command may use others).
- The conditions for the step – if the conditions aren’t satisfied, the step won’t run.
- The definition of success – a list of return codes that should be considered “successful”, typically 0 and 3010. You can also say to ignore errors, which means to ignore the return code.
Before the client computer begins to execute the task sequence, it receives (as part of the task sequence policy) the entire XML blob. That XML blob is then processed by the Task Sequence Manager, TSManager.exe, which is what actually starts the commands for each step (at least those where it has decided the conditions have been met).
So that’s a key part of what we want to do: We want to intercept each of the commands that are being executed by the TSManager.exe process before they actually start. That way, we can look at the task sequence variables currently defined, the command line details, the step’s XML, etc. How do you do this intercepting? That’s where a debugger comes in. A debugger can attach the TSManager.exe process, then set a breakpoint on the Windows API call, CreateProcessW, that is used by TSManager to run the command for each step. Each time TSManager.exe then tries to run a new command, the debugger will stop the process until you manually say continue.
That’s where the scripts come in: The provided “InsideTS” scripts take care of setting up the debugger (attaching to the TSManager.exe process, setting the breakpoint), watching for breakpoints (checking the log for “breakpoint hit” messages), and showing the current state (displaying the step details, task sequence variables, logs, etc.). The pieces involved:
- InsideTS_Attach.wsf. This is the script hooked into the task sequence itself. It needs to run at the beginning of the task sequence and then each time the computer reboots. (The debugging process doesn’t survive reboots.) It launches the next script, InsideTS_Monitor.wsf, to do the real work, waits until the debugger process (NTSD.EXE) shows up, then exits.
- InsideTS_Monitor.wsf. This script, as already mentioned, starts the debugger, NTSD.EXE. It feeds it initial commands to attach to TSManager.exe, to set the breakpoint on CreateProcessW, and to write all the debugger output to a file. The script then monitors the log file looking for “breakpoint hit” messages, and when that happens, it starts a wizard, InsideTS_Details, to show the details of what’s currently going on.
- InsideTS_DebugCommands.txt. This file contains the initial commands that are passed to NTSD.EXE.
- InsideTS_Details.xml, InsideTS_Details.vbs, and InsideTS_Header.jpg. These files form an MDT HTA wizard pane (which is why this setup requires scripts from MDT, which will be described below). This wizard pane will show three tabs:
- Task Sequence. This will give a graphical representation of the task sequence, like you would see in the task sequence editor, and will highlight the step that is about to run. (The breakpoint happens right before this step starts.)
- Variables. This will show a list of all the task sequence variables. New variables (those that haven’t been seen before) will show up in green. Existing variables that have new values will show up in yellow. Those that no longer exist (e.g. local variables that are valid only for a single task sequence step) will show up in red (showing the old value that is no longer present). And finally, those that are unchanged since the last step will not be highlighted (showing up in white).
- Step. This will show the definition of the step in two ways. First, it will show the XML definition for the step from the task sequence XML blob (which itself is stored in a task sequence variable). It will also show the MOF definition of the step (basically, the definition that the task sequence editor uses to configure the step via the GUI).
- InsideTS_TaskSequence.xsl. This is an XML style sheet that converts the task sequence XML blob into displayable HTML. The resulting HTML is displayed on the Task Sequence tab, described above, with the current step highlighted.
- InsideTS_Variables.xml. This is another XML style sheet, used to convert the list of task sequence variables (which are saved into an XML file by the InsideTS_Monitor.wsf script – they aren’t typically stored in this way) into HTML displayed on the Variables tab of the details wizard described above.
- InsideTS_MOF.xml. This file contains the definitions for each of the steps used in ConfigMgr 2012 and MDT 2012 task sequences.
Some Instructions
In addition to the files listed above, you need to gather these additional files:
- From the Windows Debugger tools download (https://msdn.microsoft.com/en-us/windows/hardware/hh852363), you need one file, NTSD.EXE.
- From ConfigMgr 2012, you need a copy of the CMTrace.exe.
- From MDT 2012, you need several files to support the scripts and wizards described above:
- Computer.png, FolderIcon.png, ItemIcon1.png, MinusIcon1.png, NavBar.png, PlusIcon1.png, Wizard,ico (graphics used in the wizard pane).
- Wizard.hta, WizUtility.vbs, Wizard.css (the MDT HTA wizard “engine”).
- ZTIDataAccess.vbs, ZTIUtility.vbs (main MDT utility scripts).
- ServiceUI.exe (a component from MDT that enables the MDT HTA wizard to be visible from the ConfigMgr task sequence, even when in the full OS).
Once you have gathered all of these files into one folder, they need to be added into the ConfigMgr boot image that you will be using and into the new OS image that you are deploying. Create an “InsideTS” folder at the root of both of these. (The simplest way to do this: mount both of the WIMs, XCOPY the folder to X:\InsideTS, commit the changes, then update the DPs.) Why do I include these files in the images? Well, it was easier to do it that way. (More on that later.)
Now that the files have been added to the boot and OS images, you then need to add commands to the task sequence to run InsideTS_Attach.wsf. How many steps you need to insert into this depends on how many reboots you expect the task sequence to perform; you need one after each reboot. At minimum, you will need two, one to run in Windows PE for preinstallation steps and a second to run in the new OS. The step should look like this:
Assuming you have set everything up right, you should be able to start the task sequence and see something like this show up:
This shows the step after the “InsideTS Attach” as being the next one to execute. You can then click on the “Variables” button and see that all of the variables are highlighted in green because they are all considered “new” (as in “never seen before”) at this point:
Once you’ve poked around enough, click the “Finish” button to close the wizard. At that point, you’ll see a strange sight: the NTSD debugger. In a perfect world, the InsideTS_Monitor.wsf script would feed the commands to continue with the step execution once you’ve clicked “Finish” on the wizard, but after messing around with that for a couple of hours, I gave up on that and went with a lower-tech approach: Type in the needed commands yourself. In case you aren’t familiar with NTSD command line options, here’s a quick reference to the ones you’ll need to know:
- “G” means go. Type G to run the step.
- “Q” means quit. You’ll have to type Q to exit the debugger after the TSManager.exe process exits (which it does before rebooting and before the task sequence completes). If you type Q before that point, the task sequence will die (it quits the debugger and the TSManager.exe process being debugged), so don’t do that. (If you do want to continue the task sequence without any more breakpoints, type “bc0” to clear the breakpoint, then “g” to continue the execution.)
That’s really all you need to know. (I used one other command, “du rdx”, to dump out the CreateProcessW command line parameter during the session, but you can see the same value at the end of the SMSTS.LOG, which you can open by clicking the “Log” button in the wizard.)
Some Caveats
Some people know the story behind this little tool: I originally put these scripts together for a BDNA “SCCM Guru” webcast back in November. The webcast was scheduled months in advance, so I assumed I had plenty of time to prepare. For a variety of reasons (including procrastination) I didn’t prepare for this nearly as soon as I had hoped. In fact, I didn’t start most of it until about 30 hours before the presentation was due to start. And for about 18 of those hours, I was travelling back to Seattle from Moscow – in coach of course. So all the preparation work was done on the airplane, with the scripting done on the Moscow to New York flight, when there was no internet connection, and the testing (and bug fixing) happening on the flight from New York to Seattle (VPN connection from the airplane to my office Hyper-V server, thank you https://www.gogoair.com). The next morning, I presented the session, completely jetlagged…
So there’s my excuse for the following caveats:
- I suspect you could add the files to the MDT toolkit files package, then put the “InsideTS Attach” step after each “Use Toolkit Package” step. That would avoid needing the files in the boot image image and OS WIMs. That may require script changes.
- I think this will work for both x86 and x64, but I’ve only tried it with x64. (Make sure you get the right platform version of NTSD.EXE and ServiceUI.EXE.) If you want it to work for both (e.g. x86 boot image deploying an x64 OS), you will likely need to make changes to the scripts.
- You should be able to use this for refresh executions as well, but you’ll then need at least three “InsideTS Attach” steps (one for the original OS, one in Windows PE, one in the new OS).
- I’ve only tried this with ConfigMgr 2012, but it should work with ConfigMgr 2007 too (although since the task sequencer runs as x86 even on an x64 OS, there might be some script updates needed to run the appropriate tools on each platform).
- This same process should work for Lite Touch task sequences too, but I’ve not tried that yet.
- I cheated on the task sequence step MOF class definitions. While the “source” files for these are in the ConfigMgr (_TaskSequenceProvider.mof) and MDT 2012 (Microsoft.BDD.CM12Actions.mof) installation directories, these files are not easy to read from a script. So I merged these files together, then put XML “wrapper” around each step to make it easier to display the MOF details.
- I tried a variety of debuggers (there are several included in the debugging tools download) to try to get one that I could drive via a script, but I had issues with them that prevented complete automation. That’s why you have to manually type “g” and “q” to interact with the debugger directly. I suspect this is fixable, but I haven’t had a chance to try it.
- Don’t use this with live, production task sequences. Think of it more as a “learning” tool that you can use in your lab to figure out what happens during a task sequence.
- Don’t call Microsoft for support. You can e-mail me with comments and suggestions if you would like. The standard Microsoft disclaimer:
This script code is provided as is with no guarantee or warranty concerning the usability or impact on systems and may be used, distributed, and modified in any way provided the parties agree and acknowledge the Microsoft or Microsoft Partners have neither accountability or responsibility for results produced by use of this script. Microsoft will not provide any support through any means.
Finally
If you manage to set this up successfully, or if you run into any issues, please e-mail me at mniehaus@microsoft.com to let me know. I think the instructions and scripts should work, but I offer no guarantees
Comments
- Anonymous
January 11, 2016
Has this been tested to work with 2012 R2 SP1? I'm trying to use this, but the TS seems to skip right over the step that's supposed to invoke the debugger. - Anonymous
January 11, 2016
The comment has been removed