Share via


OSD: Forcing a reboot

In this post I will talk about the method I use to force a reboot at the end of a ZTI task sequence; when running from OSD. This solution was put together with input from Richard Smith a fellow Deployment Guy and also with help from Avanade/Accenture - Chris Bird, Jonathan Goulding, Chris Urwin and Steven Westwell. We developed this to help us enable BitLocker as part of an OSD deployment. I'll post the scripts and steps for doing that a little later. This post covers some of the ground work that made enabling BitLocker possible, there is a whole lot more around drive partitioning - but that is for another post.

So why would we need a special way to force a reboot of a ZTI/OSD build? During the build process any reboots requested by the task sequence or applications, such as BitLocker install, are suppressed. Take a look in the log file of a build and you'll see the occasional entry saying that OSD has suppressed a reboot. You may have other things that you need a reboot for at the end of your build process.

It is important to point out that this forced reboot only occurs at the end of the OSD process. We can not force a reboot during that process and have OSD carry on.

OSD Process Overview

Before we can start writing scripts it is important to cover off what happens when the OSD process runs in a deployed OS. After an OS has been deployed and mini-setup has run the system reboots. On reboot OSD deployment (Zerotouch Installation) starts before the system has reached a logon prompt/the desktop. So OSD never actually logons to the desktop - it all happens prior to the GINA being displayed. Next time you do an OSD build watch it carefully at the end. OSD ends and you are presented with the CTRL+ALT+DEL prompt - this is the first time the OS will have reached this stage.

So knowing this how do we force our reboot? Well we have to logon of course!

The reboot process.

You may want to grab the sample scripts (see the link at the end) to follow through them as I discuss this process.

Forcing the reboot is a two stage process;

  1. Logon to the desktop
  2. run a script/cmd to reboot.

I set the system up to auto logon as part of the ZTI task list - this means I can take advantage of BDD environment variables to get the local administrator username and password. The other thing I must think about is am I going to run a script at logon or a command? If I am going to run a script then I need to grab these and place them in a directory structure outside c:\minint. Remember c:\minint gets deleted once OSD completes. The script, z-OSDPart1.wsf does these tasks. Firstly it copies down any scripts we'll need later to c:\OSDTemp. Then SetAutoRun function sets up the autologon keys and configures the runonce key to call the next script, z-OSDPart2.vbs

Once the OSD task sequence completes the system will now autologon and run the z-OSDPart2.vbs script. This second script can be quite simple (as in this example) or more complex. When I post on getting BitLocker working well see an example. So z-OSDPart2 clears out the autologon entries and issues a reboot. Note that when this runs, because it is running as a runonce command, z-OSDPart2 runs before the desktop can fully establish itself. So you will see the logon start to happen and then the machine will restart. This is a bit of a hidden bonus as anyone walking past the machine at this point will not get the chance to access the desktop while it is logged on as administrator - depending on what you have z-OSDPart2 do of course.

So your OSD machine should now have restarted and be back at a logon prompt.

When I post about getting Bitlocker working we'll actually have it logon again and do some more tasks. Remember that once OSD has completed you no longer have access to the scripts and environment variables so any tasks you get it to do must be self contained.

The sample scripts are linked below. Once you have them you will need to drop them into the distribution scripts directory and then update all your deployment point scripts directories (don't forget the ones on your SMS servers as well) so you can use them. Also because z-OSDPart1 referances z-OSDPart2 if you change the name of the second script you will need to change it in the first one as well.

 

This post was contributed by Richard Trusson a Senior Consultant with Microsoft Services, UK.

Comments

  • Anonymous
    January 01, 2003
    Hallo! We always get an error runnig these scripts like: "';' missing" and the script stops. In which Task Sequence Phase should I place the script?

  • Anonymous
    January 01, 2003
    Thanks didihai. There was an error in the wsf file. I have since updated it and reposted the zip. Anyone who has grabbed these should go get them again. To answer didihai's other question I normally put the z-osdpart1.wsf script as one of the last tasks to run in the OSD process.

  • Anonymous
    January 01, 2003
    The comment has been removed

  • Anonymous
    January 01, 2003
    You are correct and I covered this off in an earlier post. However what I am showing here are the building blocks that allow you to go and fire tasks that you can not do while in OSD - for example full BitLocker implementation.

  • Anonymous
    January 01, 2003
    The comment has been removed

  • Anonymous
    May 28, 2008
    The comment has been removed

  • Anonymous
    June 12, 2008
    The comment has been removed

  • Anonymous
    June 17, 2008
    The comment has been removed

  • Anonymous
    July 31, 2008
    The comment has been removed

  • Anonymous
    October 02, 2008
    The comment has been removed

  • Anonymous
    October 02, 2008
    Hi I am trying to implement BitLocker as a part of ZTI with SCCM 2007 R2. Is there a step-by-step guide on how to deploy BitLocker with SCCM anywhere? If not, is there a web site that can guide me in the right direction? Any help is appreciated. Thomas

  • Anonymous
    August 17, 2009
    The comment has been removed

  • Anonymous
    August 18, 2009
    Since I am very new to this, and I had help from a consultant, so pardon my verbose response in case something is "wrong" that I wouldn't know about.  Specifically, you mention that the process all occurs before the desktop loads. Not so here.  goes like this:

  1. Boot to PE
  2. Machine MAC matched to record with kicks off image deploy TS.  image restores reboot
  3. Sysprep mini setup runs reboot
  4. system comes up and DESKTOP LOADS  -In the article above I was surprised to see the suggestion that the tasks at this point should occur prior to logon dialog.  The startup session and logon session finishes, desktop loads and then about 3-5 minutes later I would get the white "Finished" screen.  Some of my techs assume the process is complete and start processing other tasks before the finished screen appears.  Is there something in my task sequence that logs me in?  I'm still getting the flow of the process ironed out in my head, trying to figure out which scripts do what where etc.
  5. if I have your "part1" loaded, I get the "deployroot not resolved" error.   -now, related to the desktop loading, these scripts will not really work well I think.  Looks like you expect the part1 to run, load "runonce" keys and then those keys fire off part2, rebooting the machine after the logon occurs.  With my desktop loading so early, this isn't going to fly so I think I have two problems:
  6. when do I load part1?
  7. should i prevent desktop from loading until after all of the TS is complete, and how? thanks again.. sorry for all the extra stuff.  So many moving parts in MDT to keep track of!  but definitely worth the effort. This is a Windows XP, SP3 image loading to a desktop class machine:

TS:

<?xml version="1.0" encoding="utf-8"?> <sequence version="3.00" name="Standard Client Task Sequence" description="A complete task sequence for deploying a client operating system">  <globalVarList>    <variable name="OSGUID" property="OSGUID">{2b403dc7-febf-4c70-8551-1fb6cfb8c708}</variable>  </globalVarList>  <group name="Initialization" disable="false" continueOnError="false" description="Initialize the TS environment" expand="true">    <step type="BDD_Gather" name="Gather local only" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">      <defaultVarList>        <variable name="GatherLocalOnly" property="GatherLocalOnly">true</variable>        <variable name="RulesFile" property="RulesFile"></variable>      </defaultVarList>      <action>cscript.exe "%SCRIPTROOT%ZTIGather.wsf"</action>    </step>  </group>  <group name="Validation" disable="false" continueOnError="false" description="Test" expand="false">    <condition>      <operator type="or">        <expression type="SMS_TaskSequence_VariableConditionExpression">          <variable name="Variable">PHASE</variable>          <variable name="Operator">equals</variable>          <variable name="Value">VALIDATION</variable>        </expression>      </operator>    </condition>    <step type="BDD_Validate" name="Validate" successCodeList="0 3010" description="" startIn="" disable="false" continueOnError="false">      <defaultVarList>        <variable name="ImageSize" property="ImageSize">0</variable>        <variable name="ImageProcessorSpeed" property="ImageProcessorSpeed">800</variable>        <variable name="ImageMemory" property="ImageMemory">512</variable>        <variable name="VerifyOS" property="VerifyOS">CLIENT</variable>      </defaultVarList>      <action>cscript.exe "%SCRIPTROOT%ZTIValidate.wsf"</action>    </step>    <step name="Check BIOS" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">      <action>cscript.exe "%SCRIPTROOT%ZTIBIOSCheck.wsf"</action>    </step>    <step name="Next Phase" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">      <action>cscript.exe "%SCRIPTROOT%ZTINextPhase.wsf"</action>    </step>    <group name="OSD Only" disable="false" continueOnError="false" expand="false" description="">      <condition>        <operator type="and">          <expression type="SMS_TaskSequence_VariableConditionExpression">            <variable name="Variable">DeploymentMethod</variable>            <variable name="Operator">equals</variable>            <variable name="Value">OSD</variable>          </expression>        </operator>      </condition>      <step type="SMS_TaskSequence_RebootAction" name="End Phase" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">        <action>smsboot.exe /target:WinPE</action>      </step>    </group>  </group>  <group name="State Capture" description="" disable="false" continueOnError="false" expand="false">    <condition>      <expression type="SMS_TaskSequence_VariableConditionExpression">        <variable name="Variable">PHASE</variable>        <variable name="Operator">equals</variable>        <variable name="Value">STATECAPTURE</variable>      </expression>    </condition>    <group name="Non-Upgrade" disable="false" continueOnError="false" description="" expand="false">      <step type="SMS_TaskSequence_RunCommandLineAction" name="Generate Application Migration File" description="" disable="false" continueOnError="false" successCodeList="0 3010" runIn="WinPEandFullOS" startIn="">        <defaultVarList>          <variable name="PackageID" property="PackageID"></variable>        </defaultVarList>        <action>cscript.exe "%SCRIPTROOT%ZTIAppXmlGen.wsf" /capture</action>      </step>      <step name="Capture User State" successCodeList="0 3010" description="" startIn="" disable="false" continueOnError="false">        <action>cscript.exe "%SCRIPTROOT%ZTIUserState.wsf" /capture</action>      </step>      <condition>        <expression type="SMS_TaskSequence_VariableConditionExpression">          <variable name="Variable">DeploymentType</variable>          <variable name="Operator">notEquals</variable>          <variable name="Value">UPGRADE</variable>        </expression>      </condition>      <step name="Capture Groups" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">        <action>cscript.exe "%SCRIPTROOT%ZTIGroups.wsf" /capture</action>      </step>    </group>    <group name="Non-OSD Refresh only" disable="false" continueOnError="false" description="" expand="false">      <condition>        <operator type="and">          <expression type="SMS_TaskSequence_VariableConditionExpression">            <variable name="Variable">DeploymentType</variable>            <variable name="Operator">equals</variable>            <variable name="Value">REFRESH</variable>          </expression>          <expression type="SMS_TaskSequence_VariableConditionExpression">            <variable name="Variable">DeploymentMethod</variable>            <variable name="Operator">notEquals</variable>            <variable name="Value">OSD</variable>          </expression>        </operator>      </condition>      <step name="Apply Windows PE" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">        <action>cscript.exe "%SCRIPTROOT%LTIApply.wsf" /PE</action>      </step>    </group>    <step name="Next Phase" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">      <action>cscript.exe "%SCRIPTROOT%ZTINextPhase.wsf"</action>    </step>    <group name="Refresh only" disable="false" continueOnError="false" expand="false" description="">      <condition>        <expression type="SMS_TaskSequence_VariableConditionExpression">          <variable name="Variable">DeploymentType</variable>          <variable name="Operator">equals</variable>          <variable name="Value">REFRESH</variable>        </expression>      </condition>      <step type="SMS_TaskSequence_RebootAction" name="Restart computer" description="" disable="false" continueOnError="false" runIn="WinPEandFullOS" successCodeList="0 3010">        <defaultVarList>          <variable name="Message" property="Message"></variable>          <variable name="MessageTimeout" property="MessageTimeout">60</variable>          <variable name="Target" property="Target"></variable>        </defaultVarList>        <action>smsboot.exe /target:WinPE</action>      </step>    </group>  </group>  <group name="Preinstall" disable="false" continueOnError="false" description="" expand="false">    <condition>      <expression type="SMS_TaskSequence_VariableConditionExpression">        <variable name="Variable">PHASE</variable>        <variable name="Operator">equals</variable>        <variable name="Value">PREINSTALL</variable>      </expression>    </condition>    <step type="BDD_Gather" name="Gather local only" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">      <defaultVarList>        <variable name="GatherLocalOnly" property="GatherLocalOnly">true</variable>        <variable name="RulesFile" property="RulesFile"></variable>      </defaultVarList>      <action>cscript.exe "%SCRIPTROOT%ZTIGather.wsf"</action>    </step>    <group name="New Computer only" disable="false" continueOnError="false" description="" expand="false">      <condition>        <expression type="SMS_TaskSequence_VariableConditionExpression">          <variable name="Variable">DeploymentType</variable>          <variable name="Operator">equals</variable>          <variable name="Value">NEWCOMPUTER</variable>        </expression>      </condition>      <step type="BDD_Validate" name="Validate" disable="false" continueOnError="false" successCodeList="0 3010" description="" startIn="">        <defaultVarList>          <variable name="ImageSize" property="ImageSize">0</variable>          <variable name="ImageProcessorSpeed" property="ImageProcessorSpeed">800</variable>          <variable name="ImageMemory" property="ImageMemory">512</variable>          <variable name="VerifyOS" property="VerifyOS">CLIENT</variable>        </defaultVarList>        <action>cscript.exe "%SCRIPTROOT%ZTIValidate.wsf"</action>      </step>      <step type="SMS_TaskSequence_SetVariableAction" name="Set Diskpart BIOS Compatibility Mode" description="" disable="false" runIn="WinPEandFullOS" successCodeList="0" continueOnError="false">        <action>cscript.exe "%SCRIPTROOT%ZTISetVariable.wsf"</action>        <defaultVarList>          <variable name="VariableName" property="VariableName">OSDDiskpartBiosCompatibilityMode</variable>          <variable name="VariableValue" property="VariableValue">TRUE</variable>        </defaultVarList>      </step>      <step type="SMS_TaskSequence_PartitionDiskAction" name="Format and Partition Disk" description="" disable="true" continueOnError="false" runIn="WinPEandFullOS" successCodeList="0 3010">        <defaultVarList>          <variable name="OSDDiskIndex" property="DiskIndex">0</variable>          <variable name="OSDPartitions0Type" property="Partitions0Type">Primary</variable>          <variable name="OSDPartitions0FileSystem" property="Partitions0FileSystem">NTFS</variable>          <variable name="OSDPartitions0Bootable" property="Partitions0Bootable">True</variable>          <variable name="OSDPartitions0QuickFormat" property="Partitions0QuickFormat">True</variable>          <variable name="OSDPartitions0VolumeName" property="Partitions0VolumeName">OSDisk</variable>          <variable name="OSDPartitions0Size" property="Partitions0Size">80</variable>          <variable name="OSDPartitions0SizeUnits" property="Partitions0SizeUnits">%</variable>          <variable name="OSDPartitions0VolumeLetterVariable" property="Partitions0VolumeLetterVariable"></variable>          <variable name="OSDPartitions" property="Partitions">1</variable>          <variable name="OSDPartitionStyle" property="PartitionStyle">MBR</variable>        </defaultVarList>        <action>cscript.exe "%SCRIPTROOT%ZTIDiskpart.wsf"</action>      </step>      <group expand="false" name="Desktop" description="" disable="false" continueOnError="false">        <action />        <condition>          <expression type="SMS_TaskSequence_VariableConditionExpression">            <variable name="Variable">IsDesktop</variable>            <variable name="Operator">equals</variable>            <variable name="Value">True</variable>          </expression>        </condition>        <step type="SMS