SCCM/MDT 2012 BUG: Deploying Windows XP via USB Fails

Problem: When deploying Windows XP/2003 using the default SCCM 2012 SP1 Task Sequence with MDT 2012 Update 1 Integration, you receive the following error when first booting into the full OS:

"Windows could not start because of a computer disk hardware configuration problem. Could not read the selected boot disk. Check boot path and disk hardware. Please check the Windows documentation about hardware disk configuration and your reference manuals for additional information."

I ran into this issue in my SCCM 2012 environment because I currently don’t have PXE boot enabled (don’t want to interfere with our production 2007 environment).  Therefore I’m using a boot USB drive for all images while I build and test.

Explanation: So as not to steal Microsoft’s thunder, I’ll just link to the TechNet article describing this and their recommended solution.

Solution: Since the MDT Task Sequence template doesn’t contain a default “Restart to WinPE” step as mentioned in the TechNet article, I created a custom Restart Computer step shortly after my own custom HTA runs (Inside the Initialization node) of the Task Sequence.  Here is a shot of the conditions I am using:

image

SCCM/MDT 2012 BUG: Deploying Windows XP Fails with Default Task Sequence Settings

At my company we are undergoing a migration from SCCM 2007 to SCCM 2012.  During this transition period I decided to take the opportunity to revamp our OSD Task Sequences to leverage more of the MDT components than we had previously done. I started this off by leveraging the new MDT templates of SCCM 2012 SP1 with MDT 2012 Update 1 integrated.

Now I know what you are saying, “XP, time to get rid of that dinosaur!”.  I know, I know but I still have to support it for a little while longer as I’m sure many of you do as well.  Ok, enough of the back story, on to the problem and resolution!

Problem: OSD cannot find the specified target to lay down the XP/2003 Image.

Cause: This is due to the default conditions on the Format and Partition Disk 5.x step in the MDT Task Sequence.  The default conditions are as follows:

clip_image001

Unfortunately with these conditions, it will never evaluate to true because it needs ALL conditions to be met in order for the step to run. 

Solution:

Therefore, we need to tweak the condition logic a bit like so:

clip_image001[4]

There, that’s better.  By moving the ImageOSVer conditions under an “If Any” rule, we can let this step run if we are deploying XP OR 2003 Server (since we can’t deploy both at the same time).

Hopefully this information will help those of you out there that still need to support XP/2003 for a while longer.

Windows KMS Activation Lost

KMS licensing is great.  It makes deployment and license management extremely easy for IT, however every now and then something “goes wrong” and the system loses its activation status.

Luckily, Microsoft has a script called slmgr.vbs that is used to register and re-register Windows.  More information on slmgr.vbs can be found at http://technet.microsoft.com/en-us/library/ff793433

In order to re-correct this behavior and get the system talking to your KMS server again, you have a few options.

  1. Disjoin the system and re-join it to the domain.
  2. Reimage the system (not exactly a time saver here)
  3. Use slmgr.vbs to re-activate Windows.  (Note: slmgr.vbs can also be used to convert MAK licenses into KMS)

Today, we’ll be covering the third method of using slmgr.vbs to re-activate a Windows Vista and above client.  First off, we’ll need to drop to a command prompt and change directories over to C:\Windows\System32

In this directory you will find the slmgr.vbs script.  You can view all of the slmgr.vbs options at http://technet.microsoft.com/en-us/library/ff793433

For this example, we simply have a KMS client who is no longer talking to the KMS server and has lost its activation status.  For this, we will use the following command: slmgr.vbs /ipk <Product_Key>

Now you may be wondering where we find the Product Key at.  Luckily for us, Microsoft uses the same KMS License Key for KMS Activation (NOTE: You do have to have a KMS Server up and running for this to work).  You can find those Product Keys here: http://technet.microsoft.com/en-us/library/ff793421.aspx

*Update* After issuing the slmgr.vbs /ipk command above, you now need to activate the key.  This forces the system to actually use the newly installed key with your KMS server.  The command for that is slmgr.vbs /ato

Updating Dell BIOS with PowerShell (Updated)

Some of you may be familiar from my earlier article “Dell BIOS Updates with PowerShell” and hopefully you have gotten some good use out of it.  There have been a few comments on that article and over time I’ve also had some issues with that version of the script brought to my attention.

Some of these issues are:

  1. 1. Dell OptiPlex 745 updates don’t work because of the naming convention
  2. 2. Bios updates are overriding newer versions that come from the factory
  3. Still not updating to the latest available version due to supersedence rules for the BIOS updates (i.e. Needing A05, then A08, then finally A12).

So with that I fired up PowerGUI and started analyzing the entire flow of the script.  And more importantly kept in mind the overall process needed when multiple versions of a BIOS Update may be required (from A01 to Axx).  With this new script, I’ve introduced some new “features”

  1. Added a loop to parse multiple available BIOS update files
  2. Added a switch condition to allow for “oddly-named” BIOS file versions (read: OptiPlex 745)
  3. Added BIOS Release Date information (Universal Time Format) to check for BIOS “Patches” (i.e. P02 on Latitude E6410/E6510)
  4. Added OSD-Specific tasks (separate script)
  5. Embedded function for actually invoking the BIOS Update process itself with custom parameters.
  6. Removed dependency on Dell OMCI for BIOS identification (using Win32_BIOS now)

Dell_BIOSUpdates.zip

Using this with OSD/MDT

I’m not going to go over the script in its entirety here, however I will put out a few things specifically for using the “OSD” version of the script.  This additional script will connect to the Microsoft.SMS.TSEnvironment in order to interact with and create a new Task Sequence Variable.

When using this with OSD/MDT, you’ll want to have the script run multiple times in order to fully update the BIOS to the latest possible revision in the case that multiple executions are necessary.  Below I’ve documented the process that I have implemented to do just this.


Task Sequence Structure:

shot_662012_104220_amAs you can see here, we have multiple nested groups that will run the Dell BIOS Update script and enforce a reboot after the update has been staged.  One thing to point out here is that after the first run (which I’m calling as a regular Package/Program) is the word “Local”.  That’s right, the OSD script is copying the model-specific BIOS Updates locally (if there is more than one) so we don’t re-download the whole package again.

Update BIOS Group Condition:

shot_662012_105011_am

Update Dell BIOS Run Commandline:
powershell.exe -NoProfile -NonInteractive -File
“C:\Temp\Dell_BIOS_Updates\Invoke-DellBIOSUpdate-OSD.ps1”

Dell_BIOSUpdates.zip

Integrating Dell XPS 13 USB 3.0 Drivers into WinPE 3.x

As most of you know by now, Dell’s “newly” released XPS 13 Ultrabook contains a USB 3.0 chipset which also means you have to deal with a new, non-native driver for use with Windows PE.  With that, here is a quick and dirty guide on what drivers are needed for the XPS 13 for Windows PE.

Download the drivers:

Obviously the first step is to obtain our drivers.  So lets go to http://support.dell.com and download them from the appropriate product page.  Here is the direct link to the current version of the driver (You’ll want to check for updated versions as this may become outdated quickly): Dell Fresco Logic xHCI (USB3) Controller FL1009 Series

Extracting the drivers:

The next step is to extract the drivers.  Using Dell’s utility or a program like 7-zip, extract the drivers to a folder.  In here is the full setup MSI and the fully extracted drivers. 

Gathering the drivers:

There are 2 drivers we will need out of this (2 per architecture, so 4 total).  In the picture below, I have highlighted the directories that contain the x86 and x64 versions of the 2 drivers you need.

image

Simply import these drivers into SCCM/MDT (remember to give them a Category!) and inject into your boot images like normal.  If done properly, you should have the following 2 drivers in your boot images:

image

Dell BIOS Updates with PowerShell

The other day I was discussing with my colleagues about how we were going to deliver Dell BIOS updates to clients during our SCCM OSD deployments.  Several solutions were brought up including using SCUP 2011, a standard software package or just saying forget it and let the desktop support technicians handle it.

We don’t yet have SCUP 2011 implemented in our environment and really don’t have the time to learn it and setup the proper processes (development, testing, release) so I set out to develop a script that would allow us to install it on all of our Dell hardware with ease.

There were 2 main criterion required of this script.

  1. It must “stage” the BIOS update but not force a reboot (OSD must handle that piece)
  2. It must be easy to update the package (even for non-scripters) to support new models or update BIOS versions

That being said, the script described below does just that.  But before we get to the script, lets take a look at the folder structure.  The main folder of the package contains the Invoke-DellBIOSUpdate.ps1 PowerShell script and a bunch of folders all corresponding to the model of a Dell system.  Inside each folder is a *SINGLE* BIOS Update File (You’ll see why I bolded the word single in a bit).

imageimage

Ok, now that we got the directory structure piece out of the way, lets get to the script.  In this first section, we simply gather the current directory, current system model and current installed BIOS version.

*NOTE: I’m referencing the new namespace for Dell OMCI 8.x.  Change this if you are using an older version of Dell OMCI*

$ScriptFolder = Split-Path -Parent $MyInvocation.MyCommand.Definition
$Model = $((Get-WmiObject -Class Win32_ComputerSystem).Model).Trim()
$BIOSVersion = (Get-WmiObject -Namespace root\DCIM\SYSMAN -Class DCIM_BIOSElement).Version

Well that was pretty easy wasn’t it?  But the work isn’t done yet.  The next few steps include:

  • Verifying there is an available BIOS Update for the current system model
  • Identify the version number of the BIOS Update File
  • Verify that a BIOS Update is needed by the system
  • Execute the BIOS Update itself
Doesn’t sound so hard now does it?  Here is the code to do it:
$ScriptFolder = Split-Path -Parent $MyInvocation.MyCommand.Definition
$Model = $((Get-WmiObject -Class Win32_ComputerSystem).Model).Trim()
$BIOSVersion = (Get-WmiObject -Namespace root\DCIM\SYSMAN -Class DCIM_BIOSElement).Version            

if(Test-Path -Path $ScriptFolder\$model)
{
 $BIOSUpdateFile = Get-ChildItem -Path $ScriptFolder\$Model
 $BIOSUpdateFileVersion = $BIOSUpdateFile.ToString() -replace ($BIOSUpdateFile.Extension,"")
 $BIOSUpdateFileVersion = $BIOSUpdateFileVersion.Substring($BIOSUpdateFileVersion.Length -3)                   

 if($BIOSVersion.CompareTo($BIOSUpdateFileVersion) -eq 0)
 {
  Write-Output "BIOS Version is up to date"
 }
 else{
  Try{
   Write-Output "BIOS Update Needed. Attempting BIOS Flash Operation..."
   #Invoke-Expression $ScriptFolder\$Model\$BIOSUpdateFile " /quiet"
   $objStartInfo = New-Object System.Diagnostics.ProcessStartInfo
   $objStartInfo.FileName = "$ScriptFolder\$Model\$BIOSUpdateFile"
   $objStartInfo.Arguments = "-noreboot -nopause -forceit"
   $objStartInfo.CreateNoWindow = $true
   [System.Diagnostics.Process]::Start($objStartInfo) | Out-Null
  }
  Catch{[Exception]
   Write-Output "Failed: $_"
  }
 }            

 Write-Output "End Dell BIOS Update Operation"
}
else
{
 Write-Output "Model Not Supported"
}

OK, now for the explanation of all that nonsense above.  The first thing we are doing in the “if” statement is checking to see if there is a folder with the current system model available.  That will tell us if the package repository is setup to support the current model.  Once we are actually inside the if-loop we create a couple more variables for use.  $BIOSUpdateFile simply gets the BIOS Update File (the .exe) and stores all it’s properties/methods into this variable.  This is now an Object!

The next variable is $BIOSUpdateFileVersion.  This variable stores the actual file version of the BIOS Update File by first stripping off the extension of the file name, then by using the Substring() method to capture only the last three characters.  As you can see from the picture above, the Dell BIOS Update file uses the A## indicator for their BIOS version.

Once we’ve gathered this information, we can then use the .CompareTo() method to compare the installed BIOS Version ($BIOSUpdateFileVersion) and the BIOS Update File Version ($BIOSUpdateFileVersion).  If they are a match, we need not proceed further and can quit.  Otherwise, we need to execute the BIOS Update File silently and without reboot.  We do this by invoking the [System.Diagnostics.Process].  Here we can set the necessary arguments, window style (CreateNoWindow for OSD) and actually Start the process.

The magic of this script is that you don’t actually  have to update the script when adding new models or updating the BIOS version.  Simply add a new folder with the appropriate name, or replace the existing BIOS update file with a new one and the script will handle the rest.

Dell OMCI 8.x–Changing the Asset Tag with PowerShell

Last fall Dell released a major revision to their Open Manage Client Instrumentation (OMCI) management extension for their enterprise systems.  With this update they chose to align their WMI Namespace and Classes with industry standards and the writable WMI Classes and their associated instances, methods and properties were moved to the following WMI Namespace: ROOT\DCIM\SYSMAN

This switch brought on some challenges for system administrators attempting to script various BIOS changes.  Today, I am going to show you how to change the Asset Tag using OMCI 8.x.

(gwmi DCIM_Chassis -namespace root\dcim\sysman).ChangeAssetTag(“newAstg”)

While already documented on Dell Tech Center, there is a bit of a “gotcha” when working with laptops while on a docking station now.  For those of you too lazy to visit the link, here is the PowerShell command to change the Asset Tag in BIOS:

The problem you will see with laptops here, is that OMCI 8 now recognizes the docking station as an additional chassis type registered in the DCIM_Chassis WMI Class. So, when running the above listed command, PowerShell “may” look at the Docking Station WMI Instance and produce an error message stating that the “ChangeAssetTag” method cannot be found.

Luckily this is easily corrected with a simple modification to the PowerShell command as follows:

(gwmi DCIM_Chassis -namespace root\dcim\sysman | Where-Object {$_.CreationClassName -ne "DCIM_DockingStation"}).ChangeAssetTag("newAstg")

As you can see, we are narrowing our search to exclude anything with the CreationClass of “DCIM_DockingStation” which will skip over the Docking Station WMI Instance and only target the main computer instance.

I hope this helps others out there.  It took me a while to track that one down.