OSD : How to build a single task sequence for Windows 7 x64 and x86


Last week I had to modify a Task Sequence created to deploy an x86 version of Windows 7, adding the option to deploy an x64 version of Windows 7. I started with the creation of a x64 Win7 OS master image using a copy of the task sequence used to create the x86 version. To adapt the x86 Task sequence to create an x64 master image, I made the following changes :

  • The boot image used should be an x64 version of WinPE, so I built it using the "Create Boot Image using Microsoft Deployment" option added by MDT 2010 to SCCM.
  • I changed the package used by the step “Apply Operating System Image” using a new one containing a x64 Version of Windows 7
  • I changed the destination value in the step “Capture Operating System Image” to reflect in the name that this is a x64 OS Master image.

We decided to have only 1 task sequence to deploy both x64 and x86 and to select which to apply in our custom HTA already used to collect other user options. Based on the user selection, our HTA has been modified to set a Task Sequence Variable PRG_PLATFORM used later in the task sequence to identify which master image to deploy. After changing the HTA, I didn’t had to modify all the steps in the task sequence, for example an x64 version of WinPE is in not required to deploy Windows 7 x64, USMT 4.0 already supports both platforms, etc. The following is the list of changes I did :

  • Added a condition “Task Sequence Variable PRG_PLATFORM equals to ‘x86’” to the step “Apply Operating System Image”
  • Added a step “Apply Operating System Image x64” with a condition “Task Sequence Variable PRG_PLATFORM equals to ‘x64’” and with the x64 master image package, previously created using the x64 master image TS.
  • Added the condition “Task Sequence Variable PRG_PLATFORM equals to ‘x86’” to all the steps that install software not compatible with Windows 7 x64
  • Added steps to install software only compatible with Windows x64 with the condition “Task Sequence Variable PRG_PLATFORM equals to ‘x64’”
  • modified the file Unattend.xml to include sections for both processorArchitecture="x86" and processorArchitecture="amd64"

I tested the new task sequence deploying a x64 version of Windows 7 and all worked as expected except that a few customizations done by custom steps were missing. I started checking the scripts used to apply those customization and immediately realized that the problem was caused by the WoW64 redirection :

The following is a snippet of an article published on TechNet Magazine (http://technet.microsoft.com/en-us/magazine/2006.01.insidemscom.aspx) that explain WoW64 redirection :

Redirection Behaviors and Dependencies

It is important for systems engineers to understand how the WoW64 redirection behavior works. There is file system and registry redirection that’s in place to help 32-bit processes work in the 64-bit environment.

File System Redirection Any time a 32-bit process attempts to access c:\windows\system32 the WoW64 layer redirects it into c:\windows\syswow64 which contains all of the 32-bit Windows binaries. This prevents a 32-bit process from trying to load a 64-bit binary. Any scripts or tools running in a 32-bit process that is referencing this directory will be automatically redirected to the syswow64 directory.

Registry Redirection A similar redirection exists for accessing the registry. Any 32-bit process trying to read or write to HKEY_LOCAL_MACHINE\Software gets redirected to HKEY_LOCAL_MACHINE\Software\Wow6432Node\. This allows separate configurations to be maintained for 32-bit and 64-bit processes. Any custom settings or keys set in this node may need to exist in both keys, as 32-bit processes will be redirected to this new branch.

Script Host Bitness Any scripts with dependencies on x86 COM objects need to be run with the 32-bit cscript or wscript. Specify either the 32-bit or 64-bit version of the script host, depending on scripting needs. Any scripts that access the redirected file system or registry are using the correct bitness script host. If a particular script runs with the 32-bit script host, it may use the WoW64 redirection and not have the expected outcome.

I found that the problem with those custom scripts running on an x64 OS is that they try to write some keys under HKLM\Software and to copy some files under %systemroot%\system32 but they ended writing keys under HKLM\SOFTWARE\Wow6432Node and files under “%systemroot%\SysWOW64”. But why redirection is enabled for those scripts? The root cause of this, is that SCCM agent is a 32 bit service even if running on a x64 OS, and so if it executes a Task sequence step of type “Run Command Line” and the command line is “cscript.exe myscript.vbs”, the 32 bit version of cscript located in %systemroot%\SysWoW64 is executed instead of the 64 bit version located in %SystemRoot%\System32. So, to solve my problem I had 2 choice :

  1. Force SCCM to execute the 64 bit version of cscript when running on x64 platforms
  2. Change those script to be aware of redirection and write in the not redirected paths when running on x64 platforms

SCCM has an option to disable Redirection on x64 platforms, so I tried the first choice using this feature :

image

With this check enabled some of the steps started to complete successfully, but not all them. I started to debug one of the failing script and I found that the script was unable to read the value of a Task Sequence Variable using the functions provided by the Class Environment defined in ZTIUtility.vbs. For reading and writing Task Sequence Variables the Class Environment uses the COM Object Microsoft.SMS.TSEnvironment but I found that if using a 64-bit version of cscript the creation of the COM object fails. The problem is that Microsoft.SMS.TSEnvironment is a 32-bit COM Object and it is not available in a 64-bit environment (Script Host Bitness). With this limitation I decided to abandon the first choice of disabling redirection and I started to change those scripts to be aware of redirection.

To create a script that is redirection aware, the first step is to identify if the Operating System in which the script is running is a 64-bit OS, to do that I used the following Function to check the Processor Architecture :

Function PRG_Isx64

    if lcase(oShell.Environment("SYSTEM")("Processor_Architecture")) = "amd64" Then
        PRG_Isx64 = True
    else
        PRG_Isx64 = False
    End if

End Function

To access the x64 System32 folder from a 32-bit application I used the alias sysnative as explained in the following article :

http://msdn.microsoft.com/en-us/library/aa384187(v=VS.85).aspx

32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access. This mechanism is flexible and easy to use, therefore, it is the recommended mechanism to bypass file system redirection. Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one.

Windows Server 2003 and Windows XP:  The Sysnative alias was added starting with Windows Vista.

The following is an example on how I used the previous function and the alias to have a variable containing the path to the not redirected system32 folder.

If (PRG_Isx64) Then
    sSysDir = oEnv("WINDIR") & "\sysNative"
Else
    sSysDir = oEnv("WINDIR") & "\SYSTEM32"
End if

Unfortunately I was not able to find an alias to access the 64 bit registry software key under a 32-bit application, so with a suggestion coming from Daniele I used WMI and the __ProviderArchitecture flag. I created a function PRG_RegWrite with the same parameters as the method RegWrite of the Wscript.Shell Object to be able to easily replace it in my scripts :

Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_CURRENT_USER = &H80000001
const HKEY_LOCAL_MACHINE = &H80000002
const HKEY_USERS = &H80000003
const HKEY_CURRENT_CONFIG = &H80000005

Function PRG_RegWrite(szKey, sValue, sType)
    Dim aKeys
    Dim rKey
    Dim strKeyPath, strValueName, sKey
    Dim objCtx, objLocator, objServices, objReg, sDelim
    Dim iCount, iMax, lRet, isKey

    if (PRG_Isx64) Then

        aKeys = Split(trim(szKey),"\")
        iCount = 0

        sKey = ucase(aKeys(0))       
        if sKey = "HKLM" or sKey = "HKEY_LOCAL_MACHINE" Then               
            rKey = HKEY_LOCAL_MACHINE
        elseif sKey = "HKCU" or sKey = "HKEY_CURRENT_USER" Then
            rKey = HKEY_CURRENT_USER
        elseif sKey = "HKCR" or sKey = "HKEY_CLASSES_ROOT" Then
            rKey = HKEY_CLASSES_ROOT
        elseif sKey = "HKEY_USERS" or sKey = "HKEY_USERS" Then
            rKey = HKEY_USERS
        elseif sKey = "HKEY_CURRENT_CONFIG" or sKey = "HKEY_CURRENT_CONFIG" Then
            rKey = HKEY_CURRENT_CONFIG       
        else
            Err.Raise 87,"PRG_RegWrite","Invalid HKEY Specified"
            Exit function
        End if
        Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
        objCtx.Add "__ProviderArchitecture", 64
        Set objLocator = CreateObject("Wbemscripting.SWbemLocator")
        Set objServices = objLocator.ConnectServer("","root\default","","",,,,objCtx)
        Set objReg = objServices.Get("StdRegProv")

        iMax = ubound(aKeys)
        if aKeys(iMax) = "" then
            isKey = true
        else
            strValueName = aKeys(iMax)
            isKey = false           
        End if
        sDelim = ""
        for iCount = 1 to iMax – 1
            strKeyPath = strKeyPath & sDelim & aKeys(iCount)
            lRet = objReg.CreateKey(rKey, strKeyPath)
            sDelim = "\"
            if lRet <> 0 then
                exit for
            end if
        next

        if isKey = false and lRet = 0 Then   
            sType = UCASE(sType)
            if sType = "REG_SZ" then
                lRet = objReg.SetStringValue(rKey,strKeyPath,strValueName,sValue)
             elseif sType = "REG_DWORD" then
                lRet = objReg.SetDWORDValue(rKey,strKeyPath,strValueName,sValue)
            elseif sType = "REG_BINARY" then
                lRet = objReg.SetBinaryValue(rKey,strKeyPath,strValueName,sValue)
            elseif sType = "REG_EXPAND_SZ" then
                lRet = objReg.SetExpandedStringValue(rKey,strKeyPath,strValueName,sValue)
            else
                lRet = objReg.SetStringValue(rKey,strKeyPath,strValueName,sValue)
            end if
        End if

        Set objCtx = Nothing
        Set objLocator = Nothing
        Set objServices = Nothing
        Set objReg = Nothing

        if lRet <> 0 Then
            Err.Raise 87,"PRG_RegWrite","Error during Write Operation  : (" & lRet & ")"
        end if
    else
        oShell.RegWrite szKey, sValue, sType
    End if

End Function

After those customizations I was able to have a single task sequence to deploy both platforms, I hope this help if someone else need to achieve the same result.

– Fabrizio

This posting is provided “AS IS” with no warranties, and confers no rights.

,

  1. #1 by Amron on September 30, 2013 - 6:15 pm

    I’m using VBS scripts to move the machine object in AD to the correct OU. Works great with XP but not with Win7 x64. So I understand that it has to do with the inability to access the COM Object. So what do I need to do in order to get these VBS scripts to work? Do I just go ahead and modify the ZTIUtility.vbs with the “Function PRG_Isx64”? If so, then how will ZTIConfigure.wsf work? Any advice would be great.

  2. #2 by Keira on June 7, 2013 - 11:45 am

    Hey very nice website!! Guy .. Excellent .. Wonderful .. I’ll bookmark your site and take the feeds also? I’m happy to find a lot of useful info here
    in the put up, we want develop extra strategies on this regard, thanks
    for sharing. . . . . .

  3. #3 by Virimai Mare on July 23, 2012 - 3:09 pm

    Hi, Please help.

    How did you manage to set-up your Task Sequence will the information. Can you please send me the task sequence

  4. #5 by berry on April 29, 2010 - 5:42 pm

    i think i really like your blog. keep posting good articel dude..!

  1. 2010 in review « Quae Nocent Docent

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.