Welcome to TechNet Blogs Sign in | Join | Help

Cravings of OSD

Cravings of OSD
Collecting USMTv4 Stats using ConfigMgr 2007 when deploying Windows 7

If you are using ConfigMgr to deploy Operating systems, and leveraging USMT (User State Migration Tool) for User State migration, you would be very much interested in finding out answers for the following questions.

  1. How long did USMT take to capture the User State data on a system?
  2. How long did USMT take to restore User State data back on a system?
  3. What was the size of the data that was migrated on each system?

Hopefully you have used USMT 4.0 with its hard link capabilities to speed things up in contrast with copying data over the network onto a remote share. Regardless of the method you had chosen for your USMT implementation, trying to capture the USMT usage statistics isn’t as simple as it sounds for all systems across your environment.

In this post, we will share the process we chose to use at Microsoft for collecting USMT statistics.

Overview of the Process

At a high level, the process of collecting USMT usage statistics can be broken down as below:

  • 1. Collect USMT usage statistics from USMT logs
  • 2. Store collected values into Task Sequence Variables
  • 3. Store Task Sequence Variables’ values into the Registry
  • 4. Use ConfigMgr inventory mechanism to report data from Registry keys.

Except for the last step of collecting inventory data using ConfigMgr, the first 3 steps are basically task sequence steps within the OS deployment task sequence.

Collect USMT usage statistics from USMT logs

This step is where we will parse USMT logs to get the required details that will be reported back to ConfigMgr site. To start with we need to know the location of the logs where the USMT executables are configured to write. Based on our configuration, the progress logs are written to %usmtlogs%\Scanprogress.log & %usmtlogs%\loadprogress.log as indicated by the command lines below.

 
"%usmtbits%\scanstate.exe" "%usmtsafe%" /o /c /hardlink /nocompress 
/efs:hardlink /i:"%usmtconf%\MigDocs.xml" /i:"%usmtconf%\SelfHostApps.xml" 
/i:"%usmtbits%\MigApp.xml" /offlinewindir:"%2" /localonly /uel:45 /v:13 
/L:"%usmtlogs%\Scanstate.log" 
/progress:"%usmtlogs%\Scanprogress.log" 
/ListFiles:"%usmtlogs%\ListFiles.txt"
"%usmtbits%\loadstate.exe" "%usmtsafe%" /hardlink /nocompress /lac /c /v:13 
/i:"%usmtconf%\MigDocs.xml" /i:"%usmtconf%\SelfHostApps.xml" 
/i:"%usmtbits%\MigApp.xml" /L:"%usmtlogs%\loadstate.log" 
/progress:"%usmtlogs%\loadprogress.log"

After locating the log files, now let’s see where the information about ‘how long it took to capture’ and the ‘size of data captured’ is hidden. For simplicity sake, we will consider only scanstate information; however the same logic is applicable for loadstate as well.

If you search for a string “, totalSizeinMBToTransfer,” in ScanProgress.log, you will locate a line that looks something like the one below. The value next to the string (16605.29) is the size of data that is captured as part of scanstate in MB. Now, it is just a matter of reading that value alone using any scripting method, and storing this value as a Task Sequence variable.

11 Sep 2009, 23:34:52 +05:30, 00:02:23, totalSizeInMBToTransfer, 16605.29

The same logic goes for finding the ‘time it took to capture the user state’, except that, this time you will be looking for a string “, errorCode,” in the same ScanProgress.log. It is usually the last line in the log with an error code of 0 if all went well. Again, using any scripting method you need to pick up the value just before the string “, errorCode”, which is 00:06:34 in the sample below.

11 Sep 2009, 23:39:02 +05:30, 00:06:34, errorCode, 0, numberOfIgnoredErrors, 0, message, "Successful run"

Store collected values into Task Sequence Variables

Before we get into, how we store the values into Task Sequence variables - why we store these data in Task Sequence variables and then move them again into registry deserves some attention.

Even though USMT data is the focus of this post, there is lots of other information that we capture which is relevant to OS deployment process. To name a few - information like OSD Start & End times, Old & New computer Names, and OSD Image Package ID are captured that are already either part of default or custom Task Sequence Variables in our deployment process. Hence, to keep the complete tracking of data in cohesion, we chose to populate USMT data also in Task Sequence Variables, and at a later state all the Task Sequence Variables’ values are collectively written to registry. So, in short, you could technically skip this step, and directly populate the USMT values into registry and jump to the last step of ‘Use ConfigMgr to report data’.

Now, let’s come back to ‘how we store values’ into Task Sequence Variables. This is a relatively easy step with only few lines of code that can do the trick. Assuming the USMT_ScanTime, USMT_ScanSize, USMT_LoadTime & USMT_LoadSize are already populated from the earlier step; it can be directly assigned to the variables after instantiating the TSEnv object as shown below.

 
SET TSEnv = CreateObject("Microsoft.SMS.TSEnvironment")
wscript.echo "--------------- Updating Task Sequence Variables 
--"
TSEnv("USMT_ScanTime") = 
USMT_ScanTime
TSEnv("USMT_ScanSize") = 
USMT_ScanSize
TSEnv("USMT_LoadTime") = 
USMT_LoadTime
TSEnv("USMT_LoadSize") = 
USMT_LoadSize

The entire script is available from our Connect site and instructions for joining that program can be found here.

Store Task Sequence Variables’ values into the Registry

With the required data in the Task Sequence variables, we are now onto the stage where we need to move them into Registry keys; which will be later collected via ConfigMgr inventory process.

Reading Task Sequence environment variables are very much similar to the method, which we saw in the earlier step. Basically, you start with instantiating Task Sequence Environment, and looping through the variables you can read them and perform any action that is required. In the snippet below, you will notice that after reading the variables, a MatchMaker function is used to compare the value against a mapping of values which need to be included or excluded.

Dim oTSE    : SET oTSE = CreateObject("Microsoft.SMS.TSEnvironment")   
For Each tV in oTSE.GetVariables() 
    IF (MatchMaker( tV, incArray ) = TRUE) Then
        IF (MatchMaker( tV, excArray ) = FALSE ) Then
            Call BrandValue( tV, oTSE(tV) )
        End IF
    End IF
 Next

If it meets the inclusion criteria and is not part of the Exclusion criteria, a function by name BrandValue is called; which will populate the registry key as seen below. Based on prior evaluation of OS architecture (64/32 bit system), appropriate reg.exe is used and the registry location is chosen.

' ////////////////////////////////////////////////////
    ' Brand a name and value to registry
    ' ////////////////////////////////////////////////////
    Sub BrandValue( theName, theValue )
    
    Dim retVal : retVal = 0
    Dim runCmd : runCmd = REGBRAND & " ADD " & REGBRANDPATH & " /F /V " & theName & " /T REG_SZ /D """ & theValue & """"
 
    Wscript.Echo " Branding : [" & runCmd & "]"
    retVal = oWSH.Run( runCMD, 0, True )
    Wscript.Echo " Result   : [" & retVal & "]"
 
    End Sub

This step is typically the last step in our task sequence to ensure we capture all the Task Sequence Variables onto registry for inventory purposes. With the data now in registry keys, we are now ready to collect that data using ConfigMgr.

Use ConfigMgr to report data from Registry Keys

Finally, after all the pre-requisite work of populating the required data in the registry of machines, we will see what needs to happen next to get that data into the ConfigMgr database for easy retrieval in the form of reports.

As with any inventory data collection using MOF in ConfigMgr, retrieval of USMT values from Registry Key here is no different. However for the sake of completeness, we will see how this is actually done within ConfigMgr. There are set of MOF files named Configuration.MOF and SMS_DEF.MOF, which control what data is collected as part of inventory agent by ConfigMgr clients. Configuration.MOF instructs ConfigMgr clients to create WMI class, and SMS_DEF.mof tells ConfigMgr clients what to pick up from the WMI class and report to ConfigMgr site up the hierarchy.

The snippets available below, pretty much do the job of collecting inventory information and reporting them to ConfigMgr site. You would need to append these snippets into the respective MOF files at the site server. Of course, after tweaking to meet your needs and testing it.

As mentioned earlier, our approach of data collection is more than just USMT and hence you see those additional lines which are not related to USMT.

Configuration.MOF snippet
 
#pragma namespace("\\\\.\\root\\CIMV2")
#pragma deleteclass("HWINV_OSD_Details", NOFAIL)
[DYNPROPS]
class HWINV_OSD_Details 
{
[key] string KeyName = "";
string TSType;
string TSVersion;
string OSDImagePackageId;
string OSDBitlockerStatus;
string OldComputerName;
string OSDComputerName;
string OSDJoinAccount;
string OSDStartTime;
string OSDEndTime;
string OSDInstallLP;
string OSDGUID;
string USMT_ScanTime;
string USMT_ScanSize;
string USMT_LoadTime;
string USMT_LoadSize;
};
[DYNPROPS]
instance of HWINV_OSD_Details 
{
KeyName = "HWINV_OSD_Details";
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|TSType"),
Dynamic, Provider("RegPropProv")] TSType;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|TSVersion"),
Dynamic, Provider("RegPropProv")] TSVersion;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|OSDImagePackageId"),
Dynamic, Provider("RegPropProv")] OSDImagePackageId;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|OSDBitlockerStatus"),
Dynamic, Provider("RegPropProv")] OSDBitlockerStatus;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|OldComputerName"),
Dynamic, Provider("RegPropProv")] OldComputerName;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|OSDComputerName"),
Dynamic, Provider("RegPropProv")] OSDComputerName;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|OSDJoinAccount"),
Dynamic, Provider("RegPropProv")] OSDJoinAccount;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|OSDStartTime"),
Dynamic, Provider("RegPropProv")] OSDStartTime;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|OSDEndTime"),
Dynamic, Provider("RegPropProv")] OSDEndTime;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\MPSD\\OSD|OSDInstallLP"),
Dynamic, Provider("RegPropProv")] OSDInstallLP;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\MPSD\\OSD|OSDGUID"),
Dynamic, Provider("RegPropProv")] OSDGUID;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|USMT_ScanTime"),
Dynamic, Provider("RegPropProv")] USMT_ScanTime;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|USMT_ScanSize"),
Dynamic, Provider("RegPropProv")] USMT_ScanSize;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|USMT_LoadTime"),
Dynamic, Provider("RegPropProv")] USMT_LoadTime;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPSD\\OSD|USMT_LoadSize"),
Dynamic, Provider("RegPropProv")] USMT_LoadSize;
};
SMS_DEF.MOF snippet
#pragma namespace("\\\\.\\root\\CIMV2\\SMS")
[ SMS_Report (TRUE),
SMS_Group_Name ("HWINV_OSD_Details"),
SMS_Class_ID ("MICROSOFT|HWINV_OSD_Details|1.0") ]
class HWINV_OSD_Details : SMS_Class_Template
{
[SMS_Report (TRUE), key ]
string KeyName;
[SMS_Report (TRUE) ]
string TSType;
[SMS_Report (TRUE) ]
string TSVersion;
[SMS_Report (TRUE) ]
string OSDImagePackageId;
[SMS_Report (TRUE) ]
string OSDBitlockerStatus;
[SMS_Report (TRUE) ]
string OldComputerName;
[SMS_Report (TRUE) ]
string OSDComputerName;
[SMS_Report (TRUE) ]
string OSDJoinAccount;
[SMS_Report (TRUE) ]
string OSDStartTime;
[SMS_Report (TRUE) ]
string OSDEndTime;
[SMS_Report (TRUE) ]
string OSDInstallLP;
[SMS_Report (TRUE) ]
string OSDGUID;
[SMS_Report (TRUE) ]
string USMT_ScanTime;
[SMS_Report (TRUE) ]
string USMT_ScanSize;
[SMS_Report (TRUE) ]
string USMT_LoadTime;
[SMS_Report (TRUE) ]
string USMT_LoadSize;
};

After the site server had a chance to create new inventory policies for clients; clients during its next inventory cycle will send the data up to its ConfigMgr site server. Once the data is processed by the data loader thread (one of the threads of SMS_Executive service), the data finally shows up in SQL database. Based on the class name we used, the below query will show data in ConfigMgr DB.

   1: SELECT * FROM V_GS_HWINV_OSD_Details

Summary

To summarize what we have seen so far - We went through the process of parsing the USMT logs for specific strings to identify the values we need to collect. After that is done, based on our implementation approach, we populated those values into Task Sequence variable and then to registry. Finally, using standard inventory collection process of ConfigMgr we saw how the MOF needs to be updated to see the data in ConfigMgr database and hence reports.

We hope this was helpful in identifying the hidden information of USMT usage statistics using few simple scripts as Task Sequence steps and the standard inventory process of ConfigMgr.

Application Discovery & OSD Results

We’ve had a great deal of customers using Modena utilizing our release on Microsoft Connect.  OSD tools and Driver Sync provide many IT administrators the ability to successfully deploy Windows 7 using the blueprint developed at Microsoft for Microsoft.  Although Windows 7 has RTM’d and is now available to business customers, the work here at Microsoft and with Modena isn’t complete.  Today’s post will outline some of the details of what we are currently working on and sharing with everyone when we expect all work completed.

Application Discovery

We’ve had requests for our internal customers that requests that, as part of the OSD process, we determine what ConfigMgr packages are installed on the computer prior to the migration to Windows 7 and flags them for re-install by OSD.  The application discovery functionality is built as a pre-flight in the OSD Wizard that executes prior to the migration.  The application discovery pre-flight (appscan.exe) executes utilizing either a local AppScanMaster.xml file that represents the <application> node that, by default, is located in the osdConf.xml configuration file or utilizing a Web service using WCF and IIS7.  For the latter, you use appscan.exe http://mywebserver/foo and the AppScanDownload.xml file is pulled from the remote web service.

To summarize the scenarios, let us explain -

    1. You can build an XML file called AppScanMaster.xml and include it in the OSD package where OSD Wizard is packaged and AppScan will scan the local SCCM repository and determine what packages are present
    2. You can install IIS7 and SQL server (we are planning to build an installer for this) and then store in a database the XML file that is downloaded by AppDiscovery from the Web service using URL

Why would one utilize #1 or #2?  I’m glad that you asked…

image

For some of our internal support needs, we needed a method that would allow administrators to manage the “master list” of packages in a more dynamic fashion without a refresh of the ConfigMgr OSD packages which is required for option #1.  If your environment is similar where packages are often added to your environment for software distribution then you should enable the Web service and utilize it as you update once and AppDiscovery honors it.  For less “dynamic” environments, you can always select option 1 as to avoid having to manage additional IIS or SQL resources.  AppDiscovery honors both the online and offline modes when executed, first attempting to use the Web service first and falling back to look for AppScanMaster.xml in the root directory where AppDiscovery is executing.

Enabling Application Discovery

Application Discovery is a single pre-flight executable that provides no User interface and depends, currently, on the OSD Wizard for the User interface.  As such, we are modifying the behavior of the OSD wizard for the applications node where an external location for the application is usable.  This is important to allow AppScan.exe to write the file to a location and for the OSD wizard to utilize it.  The current OSD Wizard locks the configuration file and thus requires another file to read in order to overwrite the default settings stored in the wizard’s configuration.

We’ve added functionality to the XML configuration and the corresponding logic in the wizard to support the ability to “link” another external file.  This is exposed in the <application> node and is indicated by remoteFile=”{filename}” as shown in the following example: [NOTE – Schema is slightly changing and this blog will be updated to reflect the new schema at a later date]

   1: <applications remoteFile=”fileName” basevariable="APPS" defaultselection="4" >
   2:  <group name="Human Resources" >
   3:   <application appid="1" name="HeadTrax" x86id="MSD0001:Headtrax Setup" x64id="MSD0011:HT64Setup" />
   4:   <application appid="2" name="Money Maker" x86id ="MSD0002:MoneyMaker2010" x64id="MSD0002:Setup" />
   5:   <application appid="3" name="Peoplesoft" x86id ="MSD0003:Peoplesoft_Setup" x64id="MSD0013:Setup" />
   6:   <application appid="4" name="Surefire" x86id ="MSD0004:SF_Setup" x64id="MSD0004:SF_Setup" />
   7: <group/>
   8: </applications>

This functionality allows the actual filename such as AppScanResults.xml to instruct the wizard to look for this file and load the data starting at the <applications> element.  After reading this file into memory, AppDiscovery will then utilize it to do a comparison against the currently installed applications.

In short, the following graphic should illustrate the pecking order of events though some of the events may occur asynchronously -

image

As indicated, the final step is to display to the end-user the application selection list that has been altered by AppDiscovery.  The behavior to the end-user is completely the same yet the default selection is now altered by AppDiscovery.  In short, all applications outlined in the Master List is always displayed to the end-user while any applications that were “discovered” by AppDiscovery are selected.

Why are the applications discovered selected?  The goal at the completion of the migration is to put the end-user right back to the state at which they were prior to the upgrade.  Though, with one noticeably bit difference, they are now running Windows 7.  If the user does “nothing” then that is the exact state they will end up in.

Getting Insight into your Migration Status – Using OSD Results

The last piece of completed, working functionality that we are readying for release is OSD Results.  At Microsoft, we focused a lot of time on getting the right blend of interaction with our end-users up front.  This is the very reason that we built the OSD Wizard that many of you are currently enjoying today.  However, we felt there was still “something” missing and it was really starting to bother many of us (ok, ok, lets just say it was bothering me the most but nonetheless we digress).  At Microsoft, we had a lot of upgrades where end-users were going from Windows 7 (Pre-RTM) to Windows 7 (RTM) and because of this they often never knew if everything worked during the migration unless the end-user poked around a bit after logging in.

Understanding that there was information we would love to communicate, we seeked out options to provide a “completion” screen when were were completed.  This was the birth of OSD Results…

How does OSD Results Work?

Utilizing a “hook” available in Windows Vista & Windows 7, we build a stand-alone Windows Presentation Foundation (WPF) application that displays a few available tabs to the end-user.  The “Tabs” are the communication channel to let the end-user know that the Deployment completed and what was the status of the key steps to the migration.  For example, we display to the end-user the Time to Complete (end-to-end), domain join information, as well as the computer system information.  We also display to the end-user the applications we installed and whether they were successful or failed.

The primary mechanism used is straight-forward and utilizes two registry keys -

  1. HKLM\SYSTEM\Setup /v CmdLine /d %windir%\modena\OSDResults.exe /f
  2. HKLM\SYSTEM\Setup /v SetupType /d 2 /t REG_DWORD /f

Why OSD Results?

As mentioned, we wanted to share with the end-user that we are “done” with our migration and that when they are ready to start working then move forward.  Leaving them at the “default” CTRL+ALT+DEL simply didn’t feel as friendly as we would have liked nor did they know whether we “succeeded” to do everything we promised to do.  Thus, the last step we execute is to do the following -

  1. Spawn an application that monitors for OSDSetupHook.exe to exit (e.g. we are watching for the task sequence to complete)
  2. We write our registry keys (see above) for OSD results to get executed
  3. We restart the computer

The end-user is then watching the system re-do the initial configuration (it really isn’t doing anything) and then WinLogon will execute the commands we put in place before reboot.

osd_results_01

 

osd_results_02

 

osd_results_03

How is OSD Results getting its Data?

OSD Results doesn’t interact, currently, on the wire as we didn’t want this to take place since we are doing all of execution prior to any login as the end-user.  OSDResults.exe runs prior to any user context thus we don’t have any hyperlinks as they would fail since the user isn’t logged in.

For simplicity, we stored all of our data in the registry.  This isn’t the most robust solution but it works.

Summary

The first question often asked is where are these bits.  We haven’t completed our final milestone, in this case, M6 that will be our feature complete.  We will finalize this over the next couple of months and will release in early November in our final, pre-RTW release.  Nonetheless, we are working to add some additional functionality that you will have in your hands real soon.

The final pieces of functionality we are putting together coming in Nov. are the following:

  1. Re-write of our underlying Wizard Schema
  2. Expanding AppDiscovery to support WQL filters as well as Many-to-One mappings
  3. Changing our Application screen in the OSD Wizard to support Application Dependencies/Exclusions/Filtering/Locking
  4. Building a Administration Tool & Installer to simplify the time to deploy for Modena’s OSD Tools

Enjoy!

-Chris

Joining Modena RC1 Tools Program

We have had a lot of discussion around the topic of our Beta program of Modena.  We are currently in a Beta released state on Microsoft’s Connect site though we are an invitation-only program.  This means that those of you who frequent Connect will not locate our beta as it is not listed in the directory.

Does this mean you can’t participate?  The answer is absolutely, positively… Well, gotcha going a bit so just so you know this is wide-open.  There are some legal things you need to do when you request your participation.

How to participate in Modena

Modena is a “collection” of tools aimed at simplifying your deployment tasks when using Configuration Manager 2007 Service Pack 2.  With Service Pack 2 (currently in Beta), you can utilize the OSD framework to deploy Windows 7 to your enterprise.  Modena, with OSD Tools and Driver Sync, includes the blueprint we use at Microsoft to deploy Windows 7.  We provide our end-user experience, exported task sequence, pre-flight scripts, and our driver sync tool to simplify management of drivers in your enterprise.

To participate in Modena RC1, the following steps should get you going:

  1. Join Configuration Manager 2007 Service Pack 2 Open Beta
  2. Using Connect, locate MPSD (under Server) and click Apply Now

image

Thanks,

-Chris

What’s New in Modena RC1 – OSD Tools & Driver Sync

In a few days, we will release our next major milestone release of the Modena tools to our Connect Beta program.  This milestone, “RC1”, is our full feature complete release of our OSD Setup Tools and Driver Sync Tool.  We will continue to iterate towards a final release later this year though most of the additions are “value add” to the Modena tools.

In this post, we wanted to take a few moments to familiarize you with some of the new features added to both the OSD Tools as well as Driver Sync.  In later posts, we will drill down deeper into each of the new features though for now we will focus on “What’s New”

OSD Tools – What’s New

The primary focus of our latest iteration is to broaden the focus of the OSD Wizard experience and to continue our focus on the IT professional’s (e.g. YOU!) ability to customize the OSD tools to your liking.  The primary 3 features added in this release are the following:


    OSD Wizard Silent Feature
    OSD Wizard Pre-Flight Capabilities
    OSD Wizard Application Selection

Let’s take a high-level look at each of the primary scenarios that drive these features in the next few sections…

Silent Feature

As you know, we offer the ability via the XML configuration (e.g. osdConf.xml) to enable or disable any page that is part of the wizard.  When enabled, the page such as Computer Details is displayed to the user.  On the other hand, if the value is disabled then the page itself isn’t displayed to the user and all values for anything that page typically shows to the end user is declared in your task sequence.

The third scenario is a the situation where the wizard is set to a silent mode.  For silent mode, the wizard checks the values of each OSD variable (such as %OSDComputerName%) to validate that the variable is set to a value other than NULL.  If NULL or not declared, the OSD wizard page that is set to silent will halt and show the page to the user requiring them to enter the data necessary for the OSD process to continue. 

For example, let’s say that you have the Computer page set to silent.  On the computer page, the end-user typically sets the variables for Computer Name, Domain/Workgroup, Organizational Unit, and last the credentials to join such domain (if needed.)  If this page is set to silent then the corresponding variables must be set for the end-user to not get prompted, otherwise, we “break silence” and ask the user for the data needed.

We felt this scenario is very useful in zero to light touch environments and can assist you in ensuring that at run-time all variables needed for a successful deployment are gathered.

Pre-Flights:  Go\No Go for Modena

As the heading indicates, this feature focuses on the scenario whereby we have a growing number of “unknown” requirements for the environments where the Modena OSD Tools are used.  For example, we have a requirement at one such customer that they would like to “customize” the machine name at run-time and not give the user the ability to edit the computer name.  In such a scenario, we need to provide the ability for them to run something at runtime in the wizard to gather some data from the machine (like service tag) and populate the %OSDComputerName% variable.  We need an engine that is robust that can handle “unknowns” without requiring a change to our core code in the wizard.

Enters the Pre-Flight page which is a new page in the Wizard that executes a series of tasks, called executables or scripts, and returns a code to the wizard.  Based on the code returned to the wizard, the end-user may or may not continue moving forward in the migration process.  The pre-flight is defined in the osdConf.xml and supports the ability to add $builtin$, stand alone executables, and Windows Script Host (VBS, etc.) scripts.  For each, you define the path to the file and what return codes are valid.  For example, Success is 0, while 1 is “Warning”, and 2 is “Error”.  You can use a wildcard “*” where errors that aren’t known prior to execution are returned thus creating a catch-all bucket that equals error.  For example, you can say as the catch-all to the user “An unknown error occurred, please contact the support desk.” and block the end-user from continuing the OSD process.  The textual string “Success”, “Warning”, and “Failure” determines the behavior the wizard takes.  The following table outlines the behavior per string:

Status

Wizard Behavior

Success The wizard successfully received return code matching integer in the XML file and will allow the user to continue
Warning The wizard successfully received return code matching integer in the XML file and will allow the user to continue
Error The wizard received a integer return code that indicates error and the end-user will have to correct the error before moving forward.  The “Next” button is grayed out.

The wizard supports an infinite number of pre-flights though this comes with a caveat.  The more pre-flights equals the longer execution of the wizard and more probability of errors.  If the wizard receives a code that it is unfamiliar with, the wizard will fail so it is up to you to ensure that you have a wildcard listed as a return code and what behavior you expect.

In our RC1 release, we will support the following built-in pre-flights that you can keep enabled or disabled:

Pre-Flight Name

Description

AC Power This determines if the end-user is running on AC Power or if battery power.  If on battery, we return an error code.

NOTE:  This only runs successfully in deployments run from a full operating system like Run Advertised Programs.  This is due to the lack of drivers to determine the correct state when running in Windows PE.
Wired LAN This determines if the computer is currently plugged into a Wired LAN connection.  If on wireless (or other connection), we return an error code.

The pre-flight page offers the following look and feel to the end-user.  This is just a sample screen shot and the actual page might slightly differ but is very, very close.

image

This is a very early screen shot and doesn’t actually show that the Next button is grayed out since there was an error.  It does though get disabled in our RC1 build.

The following is a sample XML for a pre-flight from our RC1 build:

Code Snippet
  1. <preflight>
  2.   <option check="AC Power Check" filename="$BUILTIN$:ACPOWER" >
  3.     <exitcodes>
  4.       <exitcode state="success" value="0" />
  5.       <exitcode state="error" value="*" text="No AC power detected. Please plug-in to power." />
  6.     </exitcodes>
  7.   </option>
  8. </preflight>
Application Selection:  Maximum Choice for End-Users

The last feature added to the OSD Tools was giving you the ability to configure in the osdConf.xml file a list of applications deployable by OSD.  Utilizing a feature in ConfigMgr called dynamic application provisioning, we added to our XML configuration the ability to set the base name and default selections for applications that the wizard will calculate after the user has completed the wizard.  For example, if we have a list of applications that are 1-8 and the end-user selects 1, 5, and 6 then we will pass this to the ConfigMgr dynamic application engine that only installs what the user desires.

This is the next to last page added to the wizard and also supports all features of other pages including enabled, disabled, and the silent feature.  We do not support, though, the locking of particular applications thus giving maximum flexibility to the user.  If you desire to force an application on the end-user we suggest it as a mandatory advertisement and that it not get listed to the end-user in the wizard.

In Modena, we provide a tree view that starts at “Root” and requires at least a single group below it such as HR, etc.  We do not, currently support a flat list without it as then it wouldn’t work in a tree view <grin>.  The following is a mock view of an early screen shot from our RC1 release for Modena.

image

In order to populate the tree control, we have added to the osdConfi.xml a <applications> element that defines the default data (basevariable & defaultselection) and group names along with each application as a child to the group.  For each application, we offer a App Id, Name, architecture Id (PackageID:ProgramName).

The following is a sample XML for the application page from one of our early RC1 builds:

Code Snippet
  1. <applications basevariable="APPS" defaultselection="1;5;6" >
  2.   <group name="Human Resources">
  3.     <application appid="1" name="HeadTrax" x86id="MSD0001:Headtrax Setup" amd64id="MSD0011:HT64Setup" />
  4.     <application appid="2" name="Money Maker" x86id ="MSD0002:MoneyMaker2010" amd64id="MSD0002:Setup" />
  5.     <application appid="3" name="Peoplesoft" x86id ="MSD0003:Peoplesoft_Setup" amd64id="MSD0013:Setup" />
  6.     <application appid="4" name="Surefire" x86id ="MSD0004:SF_Setup" amd64id="MSD0004:SF_Setup" />
  7.   <group />
  8.   <group name="Marketing">
  9.     <application appid="5"  name="Spinsoft" x86id="MSD0010:Setup" amd64id="MSD0010:Setup" />
  10.     <application appid="6"  name="Jargon Dragon" x86id="MSD0011:Install" amd64id="MSD0011:Install64" />
  11.     <group />
  12.   <group name="Developer">
  13.     <application appid="7"  name="Visual Studio" x86id="MSD0020:VSSETUP" amd64id="MSD0020:VSSETUP64" />
  14.     <application appid="8"  name="SQL" x86id="MSD0021:Sql_Setup_08" amd64id="MSD0021:Setup64" />
  15.   <group />
  16. </applications>

As you can see, we have been pretty busy and we apologize for not spending as much time blogging as we would like.  However, we had to lock on our features, design them, code them, and lastly test them in a 6-week sprint so our team has been heads down.  We hope that you enjoy these new features as much as we are!

Driver Sync – What’s New

The Driver Sync tool, unlike the OSD Tools, has been "feature” complete since we released it.  We have focused our attention on a lot of tweaks and optimizations in our RC1 build and the one additional piece we added was an installer. 

In the Modena RC1 build, the following features were added:


    Driver Sync Installer
    Driver Sync now utilizes device driver information based on OS
    Driver Sync now has retry logic to avoid failures

The Driver Sync tool is a complicated application that relies heavily on IIS 7.0, .NET 3.5, WSUS, and SQL.  The complexity caused some installation difficulties that we wanted to mitigate using an installer.  The primary two things added in RC1 is a full-blown installer for the Driver Sync Web & SQL services that aids in setup along with the addition of support for operating system scoping.

image

Our Driver Sync team has worked very closely with our Microsoft production patch team to get Driver Sync running in the infrastructure that runs and patches 130,000 computers at Microsoft.  The tool is optimized in every conceivable way possible though our team is continuing to look for more methods to streamline and improve.  It is ready, as are the OSD tools, for production.

Select whether to install the Driver Sync client and Database components or to install to the Web Server:

image

Validate that the Server has all the required components on your selection of what to install:

clip_image002

Get the ConfigMgr 2007 Site Database Server & Database Name:

clip_image002[5]

Summary

Our team of Program Managers, Developers, and Testers who have worked long hours with a lot of moving targets is to thank for what we believe are two valuable tools that will help our customers deploy and manage a Windows 7 infrastructure.  We will soon release the RC1 bits to our connect site and will avail ourselves to the world via the Connection Directory soon thereafter.  The BITS for Modena are available today, in Beta form, at connect.microsoft.com.

Give us a try today and let us know what you think!

Our Team – A big Thanks:

  • Cameron King
  • Ben Shy
  • Brian Wishan
  • Tim Skudlarick
  • Chris Adams
  • Susan Foley
  • Chris Barrett
  • Satya Undamati
  • Michael Schmidt
Understanding the Volume Page in the Modena Beta OSD Setup Wizard

One of the features enabled in the PXE experience (bare metal) is the volume page.  This page is disabled by default when running from Run Advertised Programs (RAP) or ARP as all the information is available from within the operating system.  In this post, I’m going to focus on explain our Modena OSD Setup Wizard’s volume page such as how to enable it but more importantly what is going on in the background based on selections made in the wizard.

Volume Checks

The first thing to note is the fact that the OSD Setup Wizard requires an NTFS partition exist otherwise we will throw an error.  This isn’t a bug in the actual OSD Setup Wizard but instead is a requirement for ConfigMgr 2007 OSD.  Thus, their is no support for RAW drives and the wizard will produce the volume page but it will be grayed out and give the warning message that no NTFS volume is present.

image 

To resolve this problem, it is pretty straight forward using these commands:

image

In short -

  1. Open Diskpart by typing Diskpart
  2. Type:

Sel Disk 0

Create Par Pri

Format fs=ntfs quick

assign letter=c:

Now give it another try and you should see the drive listed as an available volume.

WinPE vs. Full OS Configuration

It should be noted that, with our Modena Beta OSD Setup Wizard tools we deliver two configuration files.  The purpose of this is to show how to effectively have a configuration file for the wizard that supports the bare-metal experience versus the scenario where a user is running the wizard from a full OS.

File Name Purpose
osdConfWinPE.xml This file differs slightly in the fact that it is expected to be used when the Task Sequence detects that it is running in WinPE.  In this case, all pages by default are enabled in the XML including the Volume Page.
osdConf.xml This file is the default configuration used when the Task Sequence detects it is not running in WinPE (e.g. Full OS) and will disable the volume page since assumptions can be made that the end-user would like to upgrade the current OS running on this current partition.  The key thing to note here is that by default the users data will be backed up no matter what (since the format/no format in a selection on the volume page)

Enabling the Volume Page in the Configuration File

The purpose of this blog is to just make sure that those participating in the Modena Beta understand how to test and configure the OSD Setup Wizard tools.  This is the key to us getting good feedback that can drive some design changes (if necessary) that will make this wizard as useful as possible.  For this example, I’m going to outline how to modify the XML configuration file to enable the Volume page.

To enable the volume page, do the following:

  1. Open the XML configuration file (osdConf or osdConfWinPE) using your favorite XML editor
  2. Locate the <pages> element (e.g. CTRL+F)
  3. Modify the Volume page to say enabled
  4. Save the file

The enabled volume page XML should look like the following upon completion:

- <Page>
  <Option name="WelcomePage" mode="Enabled" text="Welcome." /> 
  <Option name="ComputerPage" mode="Enabled" /> 
  <Option name="NetworkPage" mode="Enabled" /> 
  <Option name="LanguagePage" mode="Enabled" /> 
  <Option name="VolumePage" mode="Enabled" /> 
  <Option name="SummaryPage" mode="Enabled" /> 
  </Page>

The disabled volume page XML should look like the following upon completion:

 <Page>
  <Option name="WelcomePage" mode="Enabled" text="Welcome." /> 
  <Option name="ComputerPage" mode="Enabled" /> 
  <Option name="NetworkPage" mode="Enabled" /> 
  <Option name="LanguagePage" mode="Enabled" /> 
  <Option name="VolumePage" mode="Disabled" /> 
  <Option name="SummaryPage" mode="Enabled" /> 
  </Page>

Multiple Image Options Available for X64 Machines

A often asked question is around how the wizard determines what to show in the Image list.  For example, a WIM might combine both a Vista & Win7 image hence leading to the user having multiple options such as:  Windows 7 (x86) and Windows Vista (x86).  This could balloon up to 4 or more options in the drop down such as the case where Vista & Win7 are offered on a x64 machine – Windows 7 (x86) and Windows Vista (x86), Windows 7 (x64) and Windows Vista (x64).

To avoid confusion by end-users, the image selection field can be locked to ensure that they are only offered what they should get.  However, in a very flexible environment where the end-users are knowledgeable, this option becomes very nice.

-Chris

Modena (OSD Tools & Driver Sync) Private Beta Released

On June 2nd, the Modena team at Microsoft reached a pivotal milestone by releasing our first semi-formal release to external users.  This is a great milestone that our team set out to accomplished back in January when we formed our engineering team.  The vision is that we develop tools that not only are used at Microsoft and our external customers but also are delivered as to customers to expedite and accelerate their deployments.  We aren’t the solution accelerator team who focuses heavily on this very goal – though often we find we have to add some additional value to their tools to meet Microsoft requirements.  As a value-add, we decided to share our tools with our customers as a way to enhance the experience you might have with our tools.

Microsoft Code-named “Modena” Beta Tools

The first thing that often comes up is what is your name.  We don’t have a name right now and may never have one.  We do have a code-name though and that is what the cool people do so we are happy.  Modena is one of the project internal names we selected and is currently our master project to deliver a enterprise-ready Configuration Manager 2007 Operating System Center (OSD) solution (wow, say that backwards 3 times!) at Microsoft.  It is comprised of two tools that each solve a particular problem at Microsoft:

Modena Beta OSD Tools

This packaged release is three parts – our custom OSD Setup Wizard – that offers a flexible, usable user experience to end-users though fully supports the powerful capabilities of ConfigMgr 2007’s task sequence engine.  For example, IT administrators can add a simple task sequence step that will show the wizard user interface as well deploy a pre-populated configuration to support different sites.  At Microsoft, we have various ConfigMgr hiearchies that cause us to have various pieces of data to offer the end-user and we can change this configuration without ever re-compiling the wizard.  I will talk more about this below. 

Beyond the wizard, we offer a set of pre-flight tools (scripts, etc.) that will enhance the user experience to ensure that a user doesn’t install Windows 7 (or another OS) when they don’t have the right set of conditions.  These conditions could be available memory, bandwidth, or A/C power.

We also deliver an exported task sequence that can easily (we think) get imported and uses the OSD Setup Wizard along with the pre-flights so that you can run with it and test to your hearts content.

Modena Beta Driver Sync Tool

Deploying Windows 7 at Microsoft posed some unique challenges that I know the rest of the world has faced.  We all know that drivers are a non-trivial activity when it comes to ensuring that machines have the right driver.  We had a hard requirement to ensure that we delivered drivers to client machines not only during OSD (think Driver Catalog) but also after Windows 7 is up & running.  For this, we developed the Driver Sync Tool. 

The Driver Sync Tool marries together three separate products, Windows Update/Microsoft Update (WU/MU), Windows Server Update Services (WSUS), and ConfigMgr 2007.  The logic between marrying these with a “tool” is that we already have all the data needed for our clients in our ConfigMgr database and all we need to do is put that together with WU/MU and push to WSUS.  Thus, just like a user is patched today using WSUS we could also provide the same experience to ensure they are provided updated drivers.

We built the Driver Sync Tool using Internet Information Services (IIS) 7.0, .NET Framework 3.5 Service Pack 1 (specifically, Windows Communication Foundation), and SQL Server 2008.  The only requirement is that you, when you download, already have a Windows Server 2008, WSUS v3 Service Pack 1, & SQL Server 2008 licensed server(s) available in your enterprise.  The Driver Sync Tool will then communicate directly to your ConfigMgr infrastructure and obtain all broken drivers and locate the best driver for that device Id (it uses a combination of device Id, compatible Id, and hardware Id’s) and then notifies your WSUS infrastructure to pull down the Update Id for that driver.  It’s that simple…Not really, but you get the point!

For more details, see this blog post that talk a bit more about how we “enabled” the Driver Sync Tool and look for future posts that talk more in-depth about our design and solution.

In order to obtain the Modena Beta Tools you will have to already be a member of the ConfigMgr 2007 SP2 Open Beta Program that is available via the Microsoft Connect site.  This is required as our tools are developed in lieu of their update (excluding Driver Sync Tool).

Modena Beta OSD Setup Wizard

Unless you attended Microsoft Management Summit in late-April, you probably have no idea what this OSD Setup Wizard is.  You might have also attended our Technet webcast on the topic and see the demonstration as we use it there.  As mentioned above, the OSD Setup Wizard is a development effort by my team at Microsoft that solves the age old dilemma of providing a nice, intuitive, yet robust user experience (UX) for clients.  We targeted the OSD Setup Wizard for Windows 7 but there isn’t anything stopping it from working fine on Windows XP, Windows Vista, etc. though obviously I would tell you that you are crazy for not deploying Windows 7 – it rocks!

The goals of the wizard are broken up today (and future) sections:

  1. Welcome
  2. Future - (it’s a secret)
  3. Computer
  4. Network
  5. Language
  6. Volume
  7. Future - (it’s a secret)
  8. Summary

The purpose of these sections are to logically place the UX together based on the purpose.  As an IT Administrator, it is easy to disabled any of these sections/pages as well as set the default configuration such as the OU, etc.  For example, look at this snippet from the osdConf.xml:

 
    <PageSettings>
      <Page>
        <Option name="WelcomePage" mode="Enabled" text="Welcome to the Windows7 OSD Setup Wizard."/>
        <Option name="ComputerPage" mode="Enabled"/>
        <Option name="NetworkPage" mode="Enabled"/>
        <Option name="LanguagePage" mode="Enabled"/>
        <Option name="VolumePage" mode="Disabled"/>
        <Option name="SummaryPage" mode="Enabled"/>
      </Page>
    </PageSettings>
    <ConfigSettings>
      <Domain>
        <Option default="true">
          <Name enabled="true">fabrikam.com</Name>
          <OU>
            <Option default="true" enabled="true">OU=Workstations,OU=Machines,DC=fabrikam,DC=com</Option>
          </OU>
        </Option>
 
        <Option>
          <Name>europe.fabrikam.com</Name>
          <OU>
            <Option default="true" enabled="true">OU=Workstations,OU=Machines,DC=europe,DC=fabrikam,DC=com</Option>
          </OU>
        </Option>
 
      </Domain>

This would produce the following Wizard page:

clip_image002

As an IT professional, though, I don’t have time to learn C/C++ which is what our wizard is developed in so I need an easy way to update the actual OU’s as we just added an IT department (great idea!).  Easy, no problem…update osdConf.xml in your package and re-distribute to the DPs and away you go:

    <PageSettings>
      <Page>
        <Option name="WelcomePage" mode="Enabled" text="Welcome to the Windows7 OSD Setup Wizard."/>
        <Option name="ComputerPage" mode="Enabled"/>
        <Option name="NetworkPage" mode="Enabled"/>
        <Option name="LanguagePage" mode="Enabled"/>
        <Option name="VolumePage" mode="Disabled"/>
        <Option name="SummaryPage" mode="Enabled"/>
      </Page>
    </PageSettings>
    <ConfigSettings>
      <Domain>
        <Option default="true">
          <Name enabled="true">fabrikam.com</Name>
          <OU>
            <Option default="true" enabled="true">OU=Workstations,OU=Machines,DC=fabrikam,DC=com</Option>
          </OU>
        </Option>
 
        <Option>
          <Name>europe.fabrikam.com</Name>
          <OU>
            <Option default="true" enabled="true">OU=Workstations,OU=Machines,DC=europe,DC=fabrikam,DC=com</Option>
          </OU>
        </Option>
     
        <Option>
            <Name>southamerica.fabrikam.com</Name>
               <OU>
                   <Option default="true" enabled="true">OU=Workstations,OU=Machines,DC=southamerica,DC=corp,DC=microsoft,DC=com</Option>
               </OU>
        </Option>
      </Domain>

 

This would produce the following wizard with the newly updated

image

Beyond just seeing that we have the OU hard-coded, notice that we have disabled the entire selection.  The scenario here is the users at a specific site are always placed in a special OU that they shouldn’t change.  No problem, we can lock this using the enabled=”false” feature in the osdConf.xml as such:

            <Option default="true">
                <Name enabled="false">redmond.corp.microsoft.com</Name>
                <OU>
                    <Option default="true" enabled="true">OU=Workstations,OU=Machines,DC=redmond,DC=corp,DC=microsoft,DC=com</Option>
                </OU>
            </Option>

Trust us when we say we did this without re-compiling a single line of code… <g>

Branding the Wizard

As we mentioned, we set out from the start to “share” everything with the world so we always went through the thought process of how to make things simple.  When we release our RC1 in mid-July, we will have made everything in the wizard configurable so that it gives complete control to the IT professional (you).  This is crucial to ensuring that we reduce our coding churn and that you get the maximum flexibility – wise, ay?

The common thing that occurs is that you don’t want to assume “our” Microsoft branding.  As we demo’d this is pretty simple to do using the same configuration file, osdConf.xml and it is done using this XML:

    <Banner>
      <FileName>Header0.bmp</FileName>
    </Banner>

This is currently using this file for the Branding -

header1

This file, called Header0.bmp, would produce the following Welcome page:

image

 

Let’s assume you didn’t like this and wanted to change this to another header, such as Header 1.  The only requirement is that you make the .bmp 630x100 (if you make it bigger, we will show it so take our advice as we probably aren’t going to fix this bug!!!!) and off you go.  So, for example, I prefer to show this Bitmap for the Europe users.  I would create a new osdConf.xml for the Europe site and I would set the <banner> section to use header1.bmp which produces the following wizard branding:

    <Banner>
      <FileName>Header1.bmp</FileName>
    </Banner>

The Image:

header2

This would produce the following Wizard branding:

image

Summary

We are working hard on some further investments in our M5 engineering milestone and we think that we are working on the features for both our OSD Setup Tools as well as our Driver Sync Tool that you (yes, you!) want.  We do though have a beta that you could participate in if you are part of the ConfigMgr 2007 SP2 beta.  If you are a part of this program, email me and feel free to request joining our beta and we will share our bits.  Beyond that, we are reaching out and asking for folks to share what they think would be enterprise scenarios for both OSD Tools & the Driver Sync Tool.

-Chris

Deploying Win7 using OSD at Microsoft Webcast Q & A – Part III

As we mentioned, we recently gave a talk as part of the Microsoft IT Showcase series that focused on what we have built for Microsoft clients with OSD.  A great number of questions were asked during this presentation and due to time constraints we were unable to answer them.  We promised to share them in a upcoming blog.  This is the final of a 3-part series where we asked the question and answered it.  Part I and Part II are available as well on our blog.

 

Q:  How many applications did you approve for Windows 7?

A:  We reviewed most, if not all, of our currently packaged applications and determined that none were packaged in such a way that there issues with User Account Control (UAC) or OS targeting.  Thus, though we reviewed 15 number of applications required for Microsoft IT users, we had none that failed to work properly on Windows 7.

 

Q:  Is Microsoft IT using XP Mode or App-V for the applications that aren’t Windows 7 compliant?

A:  We are currently not using XP Mode for our user base at Microsoft.  This is specific, though, to our environment of users who are managed using ConfigMgr and doesn’t represent all of MS IT.  We do offer users a virtual application, Adobe Reader, for 32-bit clients but we don’t require they use the application.  For compatibility purposes, App-V isn’t the right application to use but instead users should use Microsoft Enterprise Desktop Virtualization (MED-V) as this is designed to solve OS compatibility issues.  App-V is designed to solve application compatibility issues.  We currently are testing MED-V and will look to deploy later this year.

 

Q:  Did Microsoft IT package up all the applications used as part of the OSD process?

A:  We “packaged” all the ConfigMgr packages but the actual software packaging process (such as building of the MSI, etc.) came from several different sources.  In short, we packaged some but not all of the actual packages used in the OSD process.

 

Q:  Are users responsible for reloading any application not delivered during the installation process?

A:  Yes, this is correct.  We will restore application-specific data using USMTv4 but we don’t guarantee to lay back down the application.

 

Q:  If we have WinRE partitions, how are those migrated to Windows 7 using OSD?

A:  For WinRE-enabled clients, this fell into a bucket that we couldn’t support at Microsoft because it was considered a dual-boot scenario.  If this was the case and we detected it via our OSD Setup Wizard, we exit and advise the user that we detected two operating systems on either the same volume/partition or another partition (this is rather trivial using bdeedit like functionality) and would exit.  For these scenarios, the user would have to select to format completely their volumes (option in our wizard) or they would need to remove the WinRE (Windows Recovery) partition\volume and then go through the wizard process again.  This is not the most graceful of scenarios but, unfortunately, some of the underlying technologies (WinPE) have difficulty in dual-boot scenarios so we didn’t tackle this problem at Microsoft.  Sorry!

 

Q:  Why is Microsoft IT running bare metal user experience and asking them for a user Id/password?  Why not ask for a userid and try to provision based off of Active Directory (AD) information?

A:  We are sure we completely understand the question but we will give it our best shot.  The question, we believe, ask why during the WinPE bare-metal experience do we ask for the domain username and password in the OSD Setup Wizard.  The reason this occurs is due to the fact that machine objects in Active Directory are owned by the end-user who created them originally.  Thus, if the user during a bare-metal experience selects a computer name that already exists in the Active Directory OU then we need to validate they own that object.  If they do not, we either error out and ask them to select a new name or depending on the configuration of the wizard we will generate a name for them and continue own.  For those interested, we modify the configuration in osdConf.xml that is provided for the wizard.

 

Q:  Does ConfigMgr 2007 SP2 handle packages that are advertised to allow user interaction and work with OSD?

A:  We don’t allow packages to be used that are not hard-coded to silent so, unfortunately, we can’t really speak to it with a great deal of certainty.  At this time, we would speculate it would be no problem at all though we haven’t had this experience at Microsoft or elsewhere thus leading us to have to give you our best guess.  You might can find someone on the ConfigMgr forums who has done it this way and can give you concrete advice.

 

Q:  Of the 120 machines, what % do you support with ConfigMgr driver packages?

A:  We have the luxury of having a hardware team at Microsoft who owns the relationship with our various OEMs and this team provided a setup tool to our team that provision drivers on a per-model basis.  This tool was a step in our task sequence thus mitigating the requirement that we have multiple driver package payloads to support in ConfigMgr 2007.  This is possible to do though would get very, very non-trivial fast and offer a lot of possible scenarios that could easily break.  Depending on the number of models at play here, we would probably recommend you keep your driver packages low (like we did) if you have a high number of skus and have a special step that provisions (either a script or a EXE, or something) specific drivers on a per-model basis.

 

Q:  Could the machine that Microsoft IT do not load ConfigMgr driver packages for get their driver support through an internal company WU/MU?

A:  Yes, absolutely possible and how we are actually doing it at Microsoft.  The key to our Microsoft Driver Sync Tool is to ensure that WSUS 3.0 SP1 or SP2 has the correct drivers for the hardware we have in our enterprise.  This is a crucial step and Windows Server Update Services (WSUS) represents the WU/MU service but at the enterprise level allowing for some key management necessary for many enterprises.

 

Q:  Will a customer be able to host an Internal MU for driver installations for break\fix later on?

A:  This is actually called Windows Server Update Services (WSUS) and it is the only method to bring something in-house that works with Windows Update (WU) & Microsoft Update (MU).  We aren’t currently aware of this infrastructure WSUS –> WU/MU changing in the near-term thus the reason we built our Driver Update Sync tool.  As for the OSD process, we have a script (we will share later via a blog) that we run as the final step in our task sequence that grabs all critical, important, and optional security patches and drivers from WU/MU so that our clients have the necessary updates installed or available.  We are currently investigating further ways to make this more robust (a future post) but for now this is our method for ensuring that working drivers exist upon completion of the installation of Windows 7.

 

Q:  Our current experience with SMSTS.log is it doesn’t contain all the entries from a new computer nor are the messages in the history of the SMSTS.log.  Can you explain a bit about this?

A:  Yes, they roll over after so many entries. This is why we copy our logs off to various directories throughout the imaging process. This not only captures the logs before they roll over, but it also makes it nice as they are organized in directories with the name of each phase from which the logs were generated (Install OS, Setup Windows etc.). This is done by running cmd /c xcopy /E /C /I /Y %_SMSTSLogPath% %OSDStateStorePath%\Logs\StateCapture for example where %_SMSTSLogPath%  is location where logs are always kept.

 

Q:  How do you make the SMSTS.log grow as large as needed?

A: We believe this can be set through HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CCM\TaskSequence. There are entries like LogLevel, LogMaxHistory, LogMaxSize. This would require that the boot image is changed and the OS during that portion of the install. So you could either A) mount the boot and install image and then load the boot image registry hive and make the change B) Make the registry change on the fly by doing a reg import or add.

 

Thanks,

-Chris

Deploying Win7 using OSD at Microsoft Webcast Q & A – Part II

As promised, my team wanted to follow up with everyone regarding questions asked during our Webcast last week on How Microsoft IT deploys Windows 7 using Operating System Deployment.  In this blog we will focus specifically on the questions and provide answers to those questions so please excuse us if we don’t have anything “technical” in this as we are just going down the list of questions.

 

Q:  If multiple users use a single machine, does USMTv4 from WinPE backup all data related to all user profiles

A:  Yes, USMTv4 can obtain all data for all users who have currently used the client that is getting migrated to Windows 7.  This is highly configurable though via the command-line switch and for Microsoft we provided a switch for that said only migrate local and domain users who have been active in the last 45 days.  In the below example, the /uel:45 indicates to the scanstate how far to go back when migrating user profiles whether local or domain:

"%usmtbits%\scanstate.exe" "%usmtsafe%" /o /c /hardlink /nocompress /efs:hardlink /i:"%usmtconf%\MigDocs.xml" /i:"%usmtconf%\SelfHostApps.xml" /i:"%usmtbits%\MigApp.xml" /offlinewindir:"%2" /localonly /uel:45 /v:13 /L:"%usmtlogs%\Scanstate.log" /progress:"%usmtlogs%\Scanprogress.log" /ListFiles:"%usmtlogs%\ListFiles.txt"

In the case above, you can change the /uel to something other than 45 and grab all profiles.

 

Q:  What are the pre-reqs for the OSD Setup Wizard demo’d during this presentation?

A:  The OSD Setup Wizard has no pre-requirements other than having the typical ConfigMgr 2007 SP2 needed for OSD.  The wizard is completely self-contained and is made up of a single .exe (OSDSetupWizard.exe) and a customizable XML configuration file.  This wizard can run within Windows PE or via a full operating system though the behavior is slightly different but still fully controlled using the configuration file.

 

Q:  It sounds like there are pre-reqs for ConfigMgr 2007 Service Pack 2 for deploying Windows 7, is this correct? 

A:  This is correct.  The only supported method for deploying Windows 7 is to first deploy Configuration Manager 2007 SP2.

 

Q:  Can I use more than one profile when using USMTv4?

A:  As mentioned above, absolutely.  USMTv4 supports both local and domain profiles and is flexible in it’s ability of which profiles to migrate.

 

Q:  Is the OSD Wizard a part of ConfigMgr 2007 or a stand-alone product?

A:  The wizard shown was a separate, downloadable, piece of software that is packaged up as an add-on for Configuration Manager 2007 SP2.  We will make it available along with a whitepaper soon for select customers and later broadly if possible.  It doesn’t have any plans currently of shipping as part of the ConfigMgr 2007 or later products.

 

Q:  If we are involved in the ConfigMgr SP2 TAP program, are these wizards and toolsets available to us?

A:  Yes, absolutely.  If you contact us via our blog (or directly via email) we will be happy to provide you the link to join our beta program to test the wizard and provide us feedback.

 

Q:  Will this OSD setup wizard work for creating images of XP or only Windows 7?

A:  The OSD setup wizard we showed works fine with any operating system as long as you have the configuration files setup properly and the appropriate WIMs to support the other operating systems.  As demo’d by Cameron, you can easily include additional images (via the index number) that would offer the end-user Windows XP, Windows Vista, and Windows 7 and let them select accordingly.  The wizard has only a dependency on SP2 when & if it is used for deploying Windows 7.  The wizard would work with OSD out-of-box for other operating systems.

Q:  What about security groups?

A:  This is tough for us to answer here as we can get “references” to exactly what is meant by the question.  However, if you are referring to whether the wizard could be used to join security groups the answer is currently no.  This isn’t something that we typically have a need for at Microsoft though with enough feedback we could certainly considering adding such functionality if needed.

 

Q:  What the name of this XML file?

A:  The default name for the OSD Setup wizard’s XML file is osdConf.xml though this is really irrelavant.  For multiple hiearchy environments in ConfigMgr, the support exists to specify per the task sequence the wizard and include the custom configuration file for that location, site, etc.  For example, you could have two XML files – osdConfUSA.xml and osdConfEurope.xml – and use them accordingly by specifying to use the correct configuration file.  For example, osdSetupWizard.exe /xml:osdConf.xml.

 

Q:  Does the OSD Setup Wizard work with Microsoft Deployment Toolkit (MDT) 2008/2010?

A:  This is untested on our part, unfortunately, so we really can’t speak to whether it would work or not.  We are in discussions with the MDT team currently and will hopefully share more going forward about how well the integration does work and make plans to simplify that since we do realize that MDT is a very popular method for deployments.

 

Q:  Why does the XML have to appear in that command-line?  The task sequence “Apply Operating System Image” option allows the user to enter the unattended.xml in the GUI.  Why is this different and will this difference still exist in ConfigMgr 2007 SP2?

A:  To clarify, there are two configuration files in play here.  We demo’d the use of osdconf.xml (osdSetupWizard /xml:osdconf.xml) as part of the XML configuration for the OSD setup wizard (not the operating system configuration) that sets the appropriate tas sequence variables at run-time.  This configuration changes or manipulates the behavior of the wizard as it is shown to the end-user and impacts the overall user experience.  On the other hand, the IT professional build the OSD task sequence can supply a custom unattend.xml to modify\change the operating system at run-time to match it’s desired configuration.  This is a separate discussion around how to automate the deployment of Windows 7 using the Windows Automated Installation Kit (WAIK) and was outside the scope of what we were showing.  The goal of our wizard is to provide a great user experience that is fully customizable yet returns the outcome the user desires upon completion of the OSD process.

 

Q:  I have noticed that you have to create an exclusion list of NIC MAC addresses in ConfigMgr 2007 to avoid every machine from booting directly to OSD when plugged into the network.  Is there a specific reason for this?

A:  This is the base functionality offered by ConfigMgr 2007 unknown clients (PXE support).  This is simply a behavior that can’t be avoided if you advertise to the unknown clients in Configuration Manager.  If you don’t want this behavior, remove any advertisement and the exclusion problem will cease to exist.

 

Q:  Where can I get my hands on ConfigMgr 2007 SP2 to start testing Windows 7?

A:  The ConfigMgr TAP program is available on connect.microsoft.com by entering your Windows Live ID and searching for System Center Configuration Manager.

 

Summary

For now, we are going to close down and we will answer one set of last questions tomorrow from the webcast.  Though we hope these are helpful!

-Chris

How Microsoft does IT: Deploying Windows 7

Yesterday, Cameron & I delivered a webcast that we did as a live presentation at Microsoft Management Summit (MMS) 2009.  Overall, the webcast went well but Cameron & I will use the term “well” loosely as our feedback shows we could have done better.  Shame on us…<g>

Nonetheless, it was tough to fit in a live presentation that is 75 minutes into a 60-minute slot and we overall struggled and had to rush it.  However, we did hear that it wasn’t technical enough for the hard-core OSD fan and for that we are going to re-vamp a bit and see what we can do to get us a bit more “technical” in that presentation.

Quick Summary of the Webcast

  • Defined our Terms (Defintions)
  • Understanding OSD Scenarios
  • Building the solution for Microsoft IT
  • Deploying Windows 7 at Microsoft
  • Managing Drivers at Microsoft
  • Troubleshooting & Best Practices for Windows 7 & OSD

Viewing the Webcast on Demand

This webcast is available to those who couldn’t attend and hopefully we can break this out a bit into smaller pieces in webcasts and focus more on technical deep dives.

View the Webcast (Windows Live Id Required)

Question & Answers Part I

The one feedback we got is that we didn’t have time for Q & A which we hated as much as our attendees did.  We are considering some other options to possibly open us up to questions and will reach out at that time and share when that will occur.

For now, we promise to address our questions here in a couple of blog posts (there were quite a few so we will break them into a couple of posts including this one)

Did Microsoft deploy Vista Enterprise?  Our enterprise would like to start deploying the RC Windows 7, but we’d like the enterprise version.  What version (should) we be deploying?

A:  This is a great question.  At Microsoft, we didn’t do a Vista deployment using ConfigMgr & OSD.  At the time, a great deal of focus for the IT team was focused on other projects and since Microsoft already had a working solution using Remote Installation Services (RIS)/Windows Deployment Services (WDS) then this was the primary model for Vista deployments. 

As for what version of Windows 7 you should deploy, the answer is Enterprise.  However, the enterprise edition has a few requirements that should get met prior to doing this.  As was with Vista, the product key provided is what determines the version of Windows 7 you get so the key is to work with your Microsoft contact to get an Enterprise product key and use this as part of your OSD deployments.  Also, you will need to join the System Center Configuration Manager 2007 TAP program to get the Service Pack 2 release that supports Windows 7.

 

Did you package up all the applications? If not, How did you handle the manual install of applications not packages? Did you have a ton of technicians that followed the migration to install these applications?

A:  For the most part, we already had all of our packages prior to starting out on Windows 7.  We haven’t done wide-scale deployment but our OSD solution is based slightly on a couple of methods – in Task Sequence and post-install mandatory delivery. 

 

Does USMTv4 work with legacy OS’s (XP, Vista, etc.)?

A:  USMTv4 supports both Windows XP & Vista for migration of user state to Windows 7.  It doesn’t support, from our knowledge, any older operating systems than that (2000, etc.)

 

Is the OSD wizard part of Configuration Manager 2007, or a stand-alone product?

A:  The wizard was created by our team that is part of the Management Platform & Service Delivery (MPSD) team at Microsoft.  We strive in our solutions to make them as broadly usable as possible and this is the case with the Wizard we mentioned.  The Windows 7 OSD project, codenamed “Modena”, is set to release early next week to customers who participate in the System Center Configuration Manager 2007 Service Pack 2 connect program.  As part of this, you can join our private connect program to obtain the OSD wizard and driver management bits.  We are also creating a pre-release whitepaper to help you implement the wizard with the sample task sequence we have exported for you.

 

We will share more questions & answers from our webcast in a blog post before the end of this week!

Summary

We will be sharing a lot of the data we have available in our blog over the next few weeks (we are heads down locking down our RC1 solution that we are delivering for Microsoft) that should shed some light.  What you can expect to get are scripts we use for pre-flight, a more in-depth look at the Wizard, as well as a deeper dive into the Driver Update Sync tool we built to reduce broken drivers at Microsoft.

We already have a few blogs that address part of our solution just to review-

-Chris

Hiding Background with OSD - A C# Sample to Hide Window

In this post the basics for finding and hiding a window will be shown in Visual Studio 2008 (C#). As previously mentioned in Snazzy OSD status with BGInfo, hiding the Windows 7 Setup window will be demonstrated.

Creating and Compiling

First, create a simple Console Application under the C# tree.

image

Next, copy and paste the code sample below.

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;   // Namespace for Import DLL
 
 
namespace HideSetupWindow
{
 
    class Program
    {
 
        static void Main(string[] args)
        {
            // ####################
            // | Find Window
            // ####################
            int hwnd = WinAPI.FindWindow(null, "FirstUXWnd");
            Console.WriteLine("FindWindow API Result: " + hwnd.ToString());
 
            // ####################
            // | Hide Window : 0 = Hide, 1 = Show
            // ####################
            if (hwnd != 0) WinAPI.ShowWindow(hwnd, 0);
 
        }
 
        internal static class WinAPI
        {
            // ----------------------------------------------------------
            // FindWindow : http://msdn.microsoft.com/en-us/library/ms633499.aspx
            // ----------------------------------------------------------
            [DllImport("user32.dll", SetLastError = true)]
            internal static extern int FindWindow(string lpClassName, string lpWindowName);
 
            // ----------------------------------------------------------
            // Show Window : http://msdn.microsoft.com/en-us/library/ms633548.aspx
            // ----------------------------------------------------------
            [DllImport("user32.dll", SetLastError = true)]
            internal static extern int ShowWindow(int hwnd, int nCmdShow);
        }
 
        // ####################
        // NOTE: Any of the following will work...
        // ####################
        // ----------------------------------------------------------------
        //int hwnd = WinAPI.FindWindow("FirstUXWndClass", null);
        //int hwnd = WinAPI.FindWindow("FirstUXWndClass", "FirstUXWnd");
        //int hwnd = WinAPI.FindWindow(null, "FirstUXWnd");
        // ----------------------------------------------------------------
 
    }
}

Finally, compile the application.

 

Tips & Tricks

Use the code sample below to hide an instance of Notepad. Two points worth mentioning:

  1. The Class Name for Notepad windows is “Notepad”; all Notepad windows will share this common class name.
  2. The Text or Window Name for Notepad windows may vary for each window; for example, a new instance of Notepad will usually contain the window text “Untitled – Notepad”

Parameter 1 is the Class Name. Parameter 2 is the Window Name. Searching on either (or both) parameter is possible:

/* Sample 1 */ int hwnd = WinAPI.FindWindow("Notepad", null);
/* Sample 2 */ int hwnd = WinAPI.FindWindow(null, "Untitled - Notepad");
/* Sample 3 */ int hwnd = WinAPI.FindWindow("Notepad", "Untitled - Notepad

In parting, a very accommodating utility for learning and working with this type of window manipulation is Winspector.

Consolidating Your Task Sequence Part 1: How to Combine WIM images into one

Overview

If you have multiple images that you deploy but would like to reduce the amount of operation overhead in maintaining task sequences, consolidating your task sequences into one task sequence should be considered. For example if you have a task sequence that deploys an x86 image and a different task sequence to deploy the amd64 version of the image, combining these images into one WIM with multiple indexes and combining your task sequences into one task sequence is something that should be considered.

Why Combine Images

  • Combining images will reduce the amount of footprint on your servers by using single instancing.
  • Reduce the amount of operation overhead required for a task sequences as an administrator will not have to make edits in multiple task sequences.

How to Combine images

As a rule of thumb images can be combined by using the following steps:

  1. Capture ImageA
  2. Capture ImageB
  3. Rename and change the description for ImageA
  4. Mount ImageB
  5. Append the Mounted ImageB to ImageA

If there are additional images you can continue by mounting ImageC etc. and appending them to ImageA.

Capture Our Images

Now that we have gone over the procedure at a high level lets take a look at a specific example and the command needed to combine images. The purpose of this blog is not to talk about how images are captured so lets say that we have captured an image called Win7x86.wim and another image called Win7amd64.wim and we would like to combine these images. As a best practice the x86 image should be the first index in a combined image (perhaps this is just personal choice, but for the remainder of this blog it will be outlined in this way).

Rename and Change the Description for ImageA

To avoid confusion on which image is which lets start out by changing the name and description for the first image (or index) and the name of the actual file before appending additional images. Lets start by renaming the file to Win7Combined.wim. Now lets change the information in the image using the following example:

imagex /info Win7Combined.WIM 1 "Win7(x86)" "Windows 7 x86"

Using this command the first index in the WIM has had its name changed to “Win7(x86)” and its description to "Windows 7 x86".

The change can be verified by using imagex /info Win7Combined.WIM

Mount ImageB

So now we will need to mount our Win7Amd64.wim and append it to the Win7Combined.wim. This will be done using the /apply switch, which will actually extract all of the files to the directory specified. Keep in mind that whatever directory you apply the image to will need to be empty. Follow this example to mount the image:

imagex /apply "Win7Amd64.wim” 1 C:\Mount

Where 1 is the index of the image and C:\Mount is the location where the image will be applied. Of course the image can be applied to any directory as long as it is empty.

Append the Mounted ImageB to ImageA

Now the image is ready to be appended to the first image that was renamed. Use the following example to append the images:

Imagex /append C:\Mount "Win7Combined.WIM" "Win7(AMD64)" "Windows 7 AMD64"

This will append the mounted image to the x86 image that we modified at the beginning. Additionally we have set the name to "Win7(AMD64)" and the description to "Windows 7 AMD64" of the appended image.

Now that the images have been combined imageX can be used with the /info switch to see that the image count is now 2.

image

image 

Note: You can also use DISM.exe but because this is only available with Win7 WAIK imageX has been in all examples.

Managing Drivers using WSUS at Microsoft - Introduction to "Andretti"

Drivers:  Do they have to be this hard?

At Microsoft, we have ~280,000 desktops worldwide that we are managing.  We spend a great deal of time (probably too much – honestly) trying to better understand how to manage the driver ecosystem.

For example, a few months back we started running SQL queries against our ConfigMgr database to determine how many drivers we currently have in Microsoft that are broken, or as we like to refer to them, “banged out”.

WSUS vs. Windows Update\Microsoft Update

Our operations team at Microsoft is responsible for ensuring that they meet a high SLA for patching of Microsoft desktops and laptops – 95% and higher.  For those interested in the math, that is 266,000 within a very short period of time.  I will avoid saying the “time” period to protect the innocent.

We use ConfigMgr 2007 Software Update Point (SUP) for patching of the clients with integration with ConfigMgr 2007 and ironically this system works great.  However, when Microsoft IT asks us to start managing the driver ecosystem at Microsoft we were at a loss of words.  Let me explain our dilemma here…

Using Group Policy to force Windows Update\Microsoft Update

At Microsoft, it is rather “easy” to enable a group policy that forces all clients to go to Windows update and\or Microsoft update for software patches and drivers.  However, when an administrator decides to use group policy they are deciding to use Windows update & Microsoft update for both software patching and drivers.

For drivers, the publishing of driver catalogs in Microsoft & Windows update is slightly mis-leading by “ranking” due to the fact that very few drivers are marked as critical (less than 2%).  The remainder of the drivers are actually marked as optional.

This, of course, is not an ideal solution because at Microsoft we would *love* to use SUP for patching our clients and use WU\MU for drivers.  It doesn’t work this way though…

Using WSUS

We don’t use WSUS currently patching of any drivers and haven’t been for quite some time (if ever).  During the building of our Windows 7 OSD solution, Microsoft IT challenged our team to solve the “driver” problem that has hindered us for the past few years.  We were provided minimal requirements for “solving” the problem but we were told what to solve.  So off we go in building what we call the good ‘ole “State of Affairs” where we talk about every option available including the bad ones.

We discussed chaining off of another WSUS instance and to pass the buck off to another group.  For example, at Microsoft we have a dedicated Microsoft IT hardware team who works closely with the OEMs and they could manage the WSUS instance.  This idea was nix’d about as fast as it was dreamed up…

We then started investigating the feasibility of updating and managing drivers using WSUS 3.1 and we found out some interesting things.  For example…

  1. WSUS syncs only get “critical” drivers and do not sync any optional drivers
  2. There is no concept of supercedence in the WU\MU driver catalog.  This is done using a best-bmatch algorithm by the Windows Update client and WSUS\MU.

With a little bit of investigation, we determined that around 99% of the drivers released and approved for Windows Hardware Quality Lab (WHQL) are not critical thus about 1% of drivers are actually available to WSUS users.

What does ConfigMgr 2007 offer in the Driver Space?

It was obvious to us that ConfigMgr 2007 had, with its inventory capabilities, everything we needed to effectively patch drivers at Microsoft.  It was frustrating though that we didn’t have a translation feature that would pull information from ConfigMgr 2007’s metadata (or an exported list that came from ConfigMgr 2007), get what is relevant from WU\MU, and then push it to WSUS.  Then we realized…

With an easy change to the MOF file -

/------------------------------------------------          

/ SMS Driver Catalog - Device drivers information                                    

//------------------------------------------------                                             

#pragma namespace ("\\\\.\\root\\cimv2\\sms")                                     

[SMS_Report(TRUE),                                         

SMS_Group_Name("PNP DEVICE DRIVER"),                                             

SMS_Class_ID("MICROSOFT|PNP_DEVICE_DRIVER|1.0")]                                     

class Win32_PnpEntity : SMS_Class_Template                                          

{                                             

    [SMS_Report(TRUE), key]                                      

    string DeviceID;                                          

    [SMS_Report(TRUE)]                                             

    string ClassGuid;                                        

    [SMS_Report(TRUE)]                                             

    uint32 ConfigManagerErrorCode;                                       

    [SMS_Report(TRUE)]                                             

    string PNPDeviceID;

};

/------------------------------------------------                                              

// SMS System Devices - Device drivers information                                            

//------------------------------------------------                                             

#pragma namespace ("\\\\.\\root\\cimv2\\sms")                                     

[ SMS_Report     (TRUE),                                               

  SMS_Group_Name ("System Devices"),                                    

  SMS_Namespace  (TRUE),                                            

  SMS_Class_ID   ("MICROSOFT|System_Devices|1.0") ]                                      

class CCM_SystemDevices : SMS_Class_Template                                               

{                                             

    [SMS_Report(TRUE), key]                                          

    string Name;                                     

[SMS_Report(TRUE)]                                             

    string DeviceID;      

[SMS_Report(TRUE)]                                             

    string CompatibleIDs[];     

    [SMS_Report(TRUE)]                                             

    string HardwareIDs[];

    [SMS_Report(TRUE)]                                     

    boolean IsPnP;                                              

};        

…and a refresh of the hardware inventory cycle the following query would tell us what broken (bang’d out) drivers existed at Microsoft -

   1:  SELECT distinct sys.resourceid
   2:             -- MIN(dev.[TimeStamp]),pnp.DeviceID0 as DeviceId, dev.CompatibleIds0
   3:        FROM v_R_System sys
   4:              JOIN v_GS_PNP_DEVICE_DRIVER pnp
   5:                    ON sys.ResourceID = pnp.ResourceID
   6:              JOIN v_GS_SYSTEM_DEVICES dev
   7:                    ON pnp.DeviceID0 = dev.DeviceID0 and sys.ResourceID = pnp.ResourceID
   8:        WHERE 
   9:              sys.Client0 = 1
  10:              AND sys.Obsolete0 = 0
  11:              AND pnp.ConfigManagerErrorCode0>0

 

We then knew we had everything we needed to solve this problem.

Solving the Dilemma – Driver Management at Microsoft

After realizing that neither WU/MU nor WSUS could meet our needs exactly we went down the path of least desirable and decided to use code to solve the problem.  The solution needed to accomplish the following:

  1. Download only the drivers needed for our Enterprise – nothing more, nothing less
  2. Use the WSUS infrastructure for delivery
  3. Modify absolutely nothing on our clients

Ben Shy, a Program Manager on my team, owned this piece and did a awesome job of meeting these 3 important yet huge goals.  Ben’s design, codenamed Andretti (get it – Andretti as in Mario the Indy race car Driver), would use the following to solve this problem -

Feature Purpose
ConfigMgr 2007 It was determined that we could write a service that runs as a scheduled task (or manually) that would determine what Hardware Ids (PNPIDs, Device Ids, etc.) are broken in our Enterprise with a small tweak to the ConfigMgr MOF file to ensure we get this data. 

We could then easily take action on it very similar to how the client itself could take action (though most users are allowed to access WU\MU)
WSUS 3.1 We could easily push any updates we would like to have downloaded to WSUS and instruct this service to go to WU\MU and get the appropriate drivers and publish them to the WSUS catalog.
WU\MU It was determined that all the data we need is available in ConfigMgr and that we could use the WU\MU RSS feed (and a few other pieces of data) to abstract what updated drivers are available for our enterprise clients.

 

This is basically what we have built at Microsoft to manage drivers for the enterprise.  In a few upcoming posts, we will dive deeper into how we built Andretti and soon after maybe surprise ya with some bits for you to use.  We make no implied promises but you never know!

-Chris

Snazzy OSD status with BGInfo

 

Controlling the look and feel throughout OSD a very important part of creating a good user experience. Not only is the out-of-box experience a bit bland, it’s unfamiliar and confusing to someone who’s never experienced OSD before. Our goal in this article is to outline how to spice up the end-to-end deployment experience.

At a glance, a user should be able to tell:

  • What’s going on?
  • Where am I in the overall scheme of things?

Should the deployment go awry, these questions become even more important. In one glance, without looking at logs, anyone viewing the screen can answer questions such as:

  • Where did the machine fail?
  • What is the machine name?
  • Does it have an IP address?
  • Etc…

With BGInfo, the available information to display is nearly limitless; you have complete control over what details are visible and important to your organization.

A mockup of what might be used to accomplished this goal is shown below:

image

 

Showing Status

All this is possible through the use of BGInfo. With this utility, the background screen can be changed at any point in your Task Sequence.

In the mockup provided, the following practices were taken:

  1. Branding was provided to create familiarity and provide context for what is taking place
  2. Progress was grouped into 5 phases: System Backup, Install Image, Windows Setup, Install Applications, and Restore Backup
  3. One background bitmap was created for each phase; each time a phase completes, the background is changed

So, in the example given, 5 bitmaps were created. Thus, BGInfo will be called 5 times within our Task Sequence. Each bitmap represents the active “Phase” in an “On” position, and all other “Phases” in an “Off” position.

 

Creating Status Backgrounds

Since our deployment consists of 5 phases, we’ll need 5 different bitmaps. In addition to 5 different bitmaps, we actually need 5 BGInfo configuration files. BGInfo configuration files store rendering information used to display the background; these files are passed to BGInfo as parameters. 

To create a screen, open BGInfo and:

  1. Choose a background image to use
  2. Choose what computer information to display
  3. Format/Justify/Center as preferred

Defining the background image to use, color, and positioning:

image 

Defining what computer information is displayed, and where to position it:

image

Create all 5 pages in this manner, and save each BGInfo session. After completing these steps, the final list of files will look something like this:

image

 

Setting up the Task Sequence

Assuming all the required files exist in one directory, a method for calling the appropriate “Step” is necessary. This can be accomplished through a batch file containing the following:

  • "%~dp0bginfo.exe" "%~dp0step_0%1.bgi" /nolicprompt /silent /timer:0

In this manner, your Task Sequence would simply reference the package and call the batch file with a Step number:

image 

 

Maintaining Look & Feel

To maintain the look and feel across the entire deployment, there are three areas where adjusting the background image is important for consistency:

  • Task Sequence Wallpaper set through BGInfo (already covered)
  • Windows PE Wallpaper contained in the Boot Image
  • Windows Setup Phase Wallpaper

 

Boot Image

When initially starting up in Windows PE, a default built-in background image is displayed. Until your Task Sequence begins and the background batch file runs, a user will see whatever background ships in Windows PE.

Apply your own background by opening up the SCCM console, locating your boot image, and modifying its properties. Look for the “Windows PE Background” field:

image

 

Windows Setup

After applying and booting into it the new OS (after the “Setup Windows and ConfigMgr” step), an animated black background will appear for the duration of your Task Sequence. Windows Setup overlays a full-screen window named “FirstUXWnd”, displaying the text “Setup is preparing your computer for first use”. Until the Task Sequence has completed in its entirety, this window will be seen and the custom background will not.

Task Sequence background after booting into the new OS:

image

Assuming you’ve customized the first half of your Task Sequence to show a snazzy look/feel, you’ll probably want to persist this. Especially if your Task Sequence contains a large number of post-OS-install tasks, such as application installs.

One simple and safe workaround is to hide this window. Since we know the window title, we can simply search for it and send it a “hide window” message. However, this requires creating a small application to perform the hide.

Creating this application isn’t too difficult. An example of the API calls necessary to perform this is given below. Using either .NET or native C++, this is relatively simple to create.

  1. Enumerate all windows (EnumWindows)
  2. Search for the window titled “FirstUXWnd” (GetWindowText)
  3. Set the window state to “Hidden” (ShowWindow SW_HIDE | SW_SHOWNORMAL)

Once completed, run this binary from your Task Sequence immediately after the “Windows Setup and ConfigMgr” step.

Update! A complete source-code sample is available here.

You now completely control the deployment look and feel, end-to-end.

Creating a user-interactive Task Sequence experience

At Microsoft, we have the unique challenge of having to build a OSD experience that includes providing a great user experience prior to deployment of a new OS.  In our case, we had the challenge of figuring out how we could do this considering that task sequence runs in Session0 and many of our users would never get this pretty user experience. 

In the interest of helping others who have this same goal - bettering the user experience of OSD – we wanted to cover launching an interactive process from the Task Sequence (TS). No binaries are provided; this post only journals a high-level overview of creating a C++ binary to launch an interactive process.

A similar idea with source is available from The Deployment Guys.

1. What are we building?

Assuming the user interface/wizard is pre-built in the form of a standard binary (.exe), a launcher is necessary. Shown below is an example of the launcher concept, and how it might be used.

  • Binary: SessionLaunch.exe
  • Parameter: A process name to find; our next parameter will launch in the same session
  • Parameter: A process to launch interactively, in the user’s context

image

2. When is this useful?

Since processes launched under WinPE are visible, this launcher provides value only when run from an existing OS. Two of the primary modes for operating a TS are:

  • Standalone Media TS
  • Download and Execute / Download on Demand TS

With a custom launcher, a UI could be spawned from any place in your Task Sequence. It could be used to:

  • Prompt the user for information
  • Popup error information or warning dialogs
  • Show TS status, or replace the progress implemented by OSD completely (by hiding TSProgress UI via ShowWindow())

Another point worth mentioning is that a native launcher has no dependency on the .NET Framework. All API calls covered will run on Windows XP and higher. Building a launcher after this manner grants deployment flexibility, in relation to target OS and required runtimes.

3. Understanding Process Context

When running a Task Sequence within an existing Operating System (OS), all TS work is performed in SYSTEM context. As a result, all user interface (UI) wizardry you might inject wouldn’t be visible to the user (Windows Vista+). To quickly cover this (emphasis added):

Impact of Session 0 Isolation on Services and Drivers in Windows Vista
“The Microsoft Windows Vista™ operating system mitigates this security risk by isolating services in Session 0 and making Session 0 noninteractive. In Windows Vista, only system processes and services run in Session 0. The first user logs on to Session 1, and subsequent users log on to subsequent sessions. This means that services never run in the same session as users’ applications and are therefore protected from attacks that originate in application code.”

Take note of the following points:

  1. Task Sequence execution occurs in Session 0
  2. User Logon occurs in Session 1+
  3. Unless you boot and execute your TS UI in WinPE, no one will see it

4. Which Session?

Our goal is to launch a process from SYSTEM context into a session where our user interacts. Since TS execution is performed in Session 0 (non-interactive), we need to locate an alternative, interactive session which the user is running under. How can one tell which Session ID the user is operating under? One useful API to determine this might be:

  • WTSGetActiveConsoleSessionId
    ”The WTSGetActiveConsoleSessionId function retrieves the Terminal Services session that is currently attached to the physical console. The physical console is the monitor, keyboard, and mouse. Note that it is not necessary that Terminal Services be running for this function to succeed.”

In most cases, WTSGetActiveConsoleSessionID is sufficient to retrieve the working session. Unfortunately, while this session provides the physical console session ID, problems arise when multiple users are logged in (or when our target user is connected over Remote Desktop/Terminal Services). A more appropriate function for our purpose is:

  • ProcessIdToSessionId
    ”Retrieves the Terminal Services session associated with a specified process.”

Now, only one TS can execute at a time. When the TS launches, a process is spawned by the TS to show progress; this process is “tsprogressui.exe”. OSD opens this process from SYSTEM context into the active user’s session, which is precisely what we’re attempting to do. Thus, in our launcher we simply search for the OSD-spawned “tsprogressui.exe” process. By searching for this process and calling ProcessIdToSessionId against it, we can determine the session ID our UI should spawn in.

Searching processes can be accomplished through the following API calls:

  • CreateToolhelp32Snapshot
    ”Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.”
  • Process32First
    ”Retrieves information about the first process encountered in a system snapshot.”
  • Process32Next
    ”Retrieves information about the next process recorded in a system snapshot.”

An example of this is provided by MSDN; using this example, we can extract the session ID by:

  1. Inserting a string comparison in the while-loop to match “pe32.szExeFile” against the name “tsprogressui.exe”
  2. Once found, call ProcessIdToSessionId to determine which session the TS is running in

5. Launching the UI

CreateProcessAsUser

Now for the tricky part. I defer source examples for this next section to the wide world of the web, but will overview on the idea. Most important is the CreateProcessAsUser API. Using this function, it becomes possible to launch your UI from the Task Sequence in SYSTEM context, into the user’s session. When this is accomplished, your UI will be visible/interactive.

  • CreateProcessAsUser
    ”Creates a new process and its primary thread. The new process runs in the security context of the user represented by the specified token.”

The difficulty in making this call is the preparation. Numerous parameters must be created and pre-populated prior to making the call, and this is where the trouble lies.

Creating an Access Token from the user’s Winlogon

An Access Token, representing the user we wish to execute under, is required for CreateProcessAsUser. Before launching a process under the user’s session, this token must be created/duplicated. To perform this, we extract and duplicate an Access Token from the existing user’s Winlogon session.

  1. Find the “winlogon.exe” process and obtain its handle for the target user.
    This can be done by looping through processes (shown previously) and matching the process name and session:
    • Loop through processes…
    • If process name (pe32.szExeFile) is “winlogon.exe” …
    • If process session ID (ProcessIdToSessionId) matches our user’s session ID, grab the Process ID (PID)
  2. Call OpenProcess against the PID.
  3. Extract a handle to the Winlogon token using OpenProcessToken.
Elevating token privileges with SE_DEBUG_NAME

Once a handle to Winlogon is obtained, an Access Token can then be extracted. First, a template containing the privileges we require is necessary (LUID type); this will be used when creating/duplicating our Access Token (TOKEN_PRIVILEGES object).

  1. Use LookupPrivilegeValue to find the LUID representing SE_DEBUG_NAME
  2. Create a new TOKEN_PRIVILEGES object
  3. Call DuplicateTokenEx using the handle from our user’s Winlogon; our desired access is MAXIMUM_ALLOWED
  4. Call SetTokenInformation with the previously extracted Session ID (where our UI will execute)
  5. Call AdjustTokenPrivileges to merge/append privileges from the LUID template, into our duplicated token
Launching, waiting, and returning

While many other parameters are required, they’re much simpler to generate. Creating the Access Token is the tricky part; MSDN documentation and other code samples suitably cover the rest. However, when launching from a TS you’ll likely need to wait for the process to end, and want to know the resulting exit code. Launch, wait, and process the return code in this order:

  1. CreateProcessAsUser( …, &piConsole)
  2. WaitForSingleObject(piConsole.hProcess, INFINITE);
  3. GetExitCodeProcess(piConsole.hProcess, dExitCode);

6. Summary

This is all it takes… a little bit of code and a little bit of work and you can give a “new” face to OSD like never before thought of.  To wrap up the order presented for creating a launcher:

  1. Find where “tsprogressui.exe” is executing (session ID)
  2. Find the corresponding “winlogon.exe” process associated with that session
  3. Duplicate the token
  4. Set the token session
  5. Adjust the token privilege
  6. Launch the process
  7. Wait
  8. Extract and return the exit code

7. Troubleshooting Tips

A few small tips to consider when developing, testing, or troubleshooting.

PsExec

Working between SYSTEM and USER context can be difficult and complex. PsExec is invaluable for troubleshooting; this utility can open a process in SYSTEM context, allowing the ability to test your binary. To open a SYSTEM context command-line, run the following from an elevated command window:

  • psexec –s –i –d cmd.exe
Task Manager: Adding the Session ID Column

It’s useful to see what tasks are executing under which Session ID. Add the “Session ID” column to Task Manager:

image

How to enable OSD deployments from PXE without losing WDS functionality

Overview

Customer’s may want to keep their WDS images and functionality while allowing for all the richness OSD provides. However, if they setup a PXE service point role on their WDS server then OSD is the first PXE provider in the list and therefore users will not be able to use WDS or RIS images. So if you ever wanted to know how to enable PXE support for OSD without loosing your WDS functionality then this post is for you.

The scenario is one where the administrator wishes to add a CM07 boot image directly to an existing WDS infrastructure, without using the CM07 PXE Service Point.  This works for sites configured for both mixed and native mode. Basically, this involves using bootable task sequence media to create the variables.dat file necessary to obtain the MP and certificates necessary to communicate with the site systems.

Setup

  1. Create bootable TS Media using the Wizard
  2. Extract the created ISO file to a folder using a utility such as WinRAR
  3. Mount the boot.wim using imagex /mountrw switch from the expanded ISO file (\sources\boot.wim) using the WAIK
  4. Copy the “data” folder from the extracted ISO to the SMS folder of the mounted WIM.

     

    Data Folder

     

  5. Modify the tsbootshell.ini in \sms\bin\i386 of the mounted WIM ConfigPath=X:\sms\data (give yourself rights to this file if necessary)
  6. Unmount and commit the changes to the WIM.
  7. The boot image now has the necessary path to the variables contained in the DATA folder.
  8. Add the boot image to WDS as you would any other boot image.

Note

This must be done for each site server as the MP information etc. is hardcoded into the files in the DATA folder. Additionally for each WDS server it must be determined which site servers clients should connect to and have the appropriate modified boot image hosted on those servers.

More Posts Next page »
Page view tracker