Wednesday, June 22, 2011

Windows7 - Scripted Installs, Sysprep and Configuration Passes

A few months ago the development wheel starting turning again in my office. The focus this time was on Windows 7 -our baseline OS here is Windows XP, and the push to Windows 7 next year is inevitable.

We’ve got a software factory of sorts –two tireless packagers who spend their days creating wonders with vbscript (and occasionally WISE) to produce their hundred or so packages annually. I’m guessing at the number –I’ve never counted. It’s more fingers and toes than I’ve got that’s for sure.

And then of course we have our image factory. This uses scripted OS installs, and a vast number of configuration and software jobs to produce the desired XP image. The process is neat –the images are configured with Sysprep to work on all the 30 or so hardware variations we support. Using Altiris we just assemble a job list, and overnight we can set it off to script the OS, apply windows updates, the configs and then all the software. To complete, it’s a sysprep and upload.

It’s all lovely and automated. And we can’t afford to move to Windows 7 until we have complete parity with XP in our imaging process. In short we need to keep the staff overhead down, so an automated process which injects smoothly into the current process is essential. The packagers were itching to begin testing on Windows 7, so as the imaging guy it was time for me to get moving.

Here was my checklist –very modest you’d think,

1. Find out how Windows 7 installs.
2. Find out how to script the installation of Windows 7
3. Find out how to sysprep Windows 7
4. Find out how to tweak sysprep images on delivery

I thought it would be easy -I wasn't even thinking hardware independent imaging at this point. But it wasn’t as straightforward as I had hoped -I had to actually read the docs.

1. Find out how Windows 7 Installs

After a few days scanning MSDN, I started trying to piece together the install process in my head. It turned out that we still have setup phases in Windows 7, but as we’re talking about Microsoft here, the terminology has of course changed,,

But that’s where the similarity ended with XP. Microsoft had provided an overwhelming depth of granularity to how Windows 7 installs through something called configuration passes. These appeared to be specific entry points into the Windows install process through which administrators could customise the install. There are 7 in total, and I’ve summarised each in the table below,
,

These passes were frankly imposing, but they were also evidently the key to understanding how to deploy windows 7. Each pass would be executed at specific point in the windows setup, allowing your preconfigured settings to be layered into the installation process. The entity controlling how these passes were configured was an XML file, and a quick scan of the internet will revealed a hideous number of them. And all of them ugly -in that special way that only XML can manage to be.

It was all a bit off putting, so I tried to put it all into context. I thought it best to go through and document a manual installation. So, I fired up a virtual machine, mounted our volume license Windows 7 ISO image and started making the following notes.

The screens which required some sort of input were as follows,

1. Enter Language, Keyboard and Time/Currency Format

This was the start of what Microsoft call the “Collecting Information” stage, and is part of the Windows PE phase.

2. Confirm Install

Once I clicked “Install Now”, setup had officially started.

3. Eula

As usual, this needs to be accepted before proceeding.

4. Installation Type –Upgrade or Custom?

It’s a new install, so I clicked “Custom”

5. Windows Install Location

Here we are shown the disks which are available to install Windows. I was setting this up on a modest VM with a 10GB single disk. So all I had to do was just click ‘Next’

6. Installing Windows…

This marks the end of the ‘Collecting Information’ phase, and have moved onto the “Installing Windows” stage.

Once the installation features have finished, the updates will install and the installation will automatically reboot. After the reboot, the setup informed me that it was "Updating the registry" and "Starting the Windows Services" so that it can complete the installation.

Once the final configuration was complete, setup once again rebooted the computer.

7. User Account Entry

Ah yes. It wants us to create a new account as using the administrator account is a no-no. Sensible.

8. User Password Entry

Easy enough. Like every good admin here I entered "password".

9. Windows Protection

10. Time and Date Settings

Well it says London, and that's pretty close. So I clicked 'Next'.

11. Network Location

After this, the windows settings were finalised and I was you able to logon. Windows 7 was installed!

Next I took a step back and reviewed the install process. I’m a sucker for powerpoint as a graphic builder, so I fired it up and starting to make a stab at summarising what I saw. The graphic below is the result, where each of the points itemised above in the install process are now represented by boxed number ranges.

So, user input was only required in the WinPE and Windows Welcome phases –these being at the start and end of the installation (step 6 wasn't really a user input stage, but more of a marker that the install process had begun). The graphic was comforting, but I knew the next step was going to try and reconcile this with the configuration passes.

So, I jumped, and dived. I immersed myself for two days in Windows 7 scripted installs and sysprep, downloading other peoples XML to configure the configuration passes. What didn’t work was as invaluable as what did, and at the end you’ll be delighted to hear I came up with another PowerPoint graphic.

And this graphic too was very comforting, so to spread the love I’ve pasted it below. The good news was that although there were 7 configuration passes, I would likely only ever need to worry about 4 of them. Very comforting indeed –anything which means I’ve achieved less work is worthy of a drink of two, so I went to the pub to congratulate myself.

The summarise the above picture: the deployment tree has two branches -one for scripted installs and another for sysprep. What is important to note is that during a scripted installation, we will only be considering the following passes,

And for sysprep deployments only these,

That of course begged the question what the other passes are for. We'll the Generalize pass is in the image creation stage, and is largely transparent to us -it's all run from sysrep when we seal our image. The Audit passes (yuch!) are aimed for those wanting to use Audit mode for preparing images, which seemed to be introducing a manual phase to image preparation. Hmm.. not for me. I needed parity with our XP setup –I needed complete automation. Complete power!! [Manic Laughter]. I digress…..

And this is where it got messy. I could put it off no longer. In order to write my own XML I would need to download the Windows Automated Installation Kit, the WAIK.

2. Find out how to script the installation of Windows 7

With each OS release, Microsoft releases a set of tools to help you configure and deploy that OS. With XP you had Microsoft's Deployment Tools, and with Vista/Windows 7 you have the Windows Automated Installation Kits. If I want to create my own XML files (rather than nick someone elses) the WAIK is the only way. Here's what I did:

  1. Downloaded the Windows7 WAIK from Microsoft.com (this downloads as a 1.7GB ISO image KB3AIK.ISO)
  2. Mount the ISO using the ISO mounter permanently resident on my workstation - Daemon Tools (although no reason why you couldn't use Virtual CloneDrive, even mount the disk in a VM, or even burn the ISO to DVD)
  3. Navigated to the root of the DVD, and double-click StartCD.exe (autoruns are naughty-naughty badness afterall)
  4. In the WAIK welcome screen, I proceeded directly to the install.

  5. So, the underlying MSI kicked-off and I turned off the brain cells as I clicked as many 'Next', 'I Agree' and 'OK', and 'What the Heck' buttons as required until its done. This took a while -the ISO was fairly large remember....
  6. All done, so I closed the WAIK welcome window

So, I gleefully scanned the Start Menu, and saw the entry "Microsoft Windows AIK". Within this folder I found the "Windows System Image Manager", the application which generates the XML files I needed to drive the configuration phases for my scripted installations and sysprep deliveries. This is often referred to as Windows SIM for short. Hmm... SIM... sounds strangely familiar somehow....

On firing up the Windows SIM, I was presented with the nice clean interface below. This is indeed comforting -its exactly the same jpg as others have observed.

This screen is split into 5 sections,

  1. Distribution Share
    This is so that you can point SIM at a distribution share with Windows 7 install and configuration files. We won't be looking at distribution shares today.
  2. Windows Image
    This is so you can point SIM at a Windows 7 image file, and browse the components within.
  3. Answer File
    This pane allows you to build your answer file by configuring answers to selected components
  4. Properties
    This gives a more detailed view of any component parameters you might want to configure
  5. Messages
    This pane presents errors and warnings for the answer file build process

The next task is then to use Windows SIM to create an answer file which Windows Setup will use to automate the installation. SIM will allow us to view all of the components available in a Windows image so that we can add component settings to our answer file for specific configuration passes. In order for SIM to view the components in a windows image, we'll first need to point it at the windows image file for our particular Windows 7 flavour.

  1. From the File menu, I selected the option "Select Windows Image"
  2. Now I had to point SIM at my chosen Windows 7 distribution's install.wim file (or the associated catalogue file). This could be from the DVD mounted on the same computer I'm running SIM from (or from a physical DVD of course), or from a filesystem where the DVD contents have been copied. With the DVD ISO mounted, I navigate to the sources folder, and located the catalogue file as illustrated below,

    This resulted in the Windows Image section being populated as follows,

  3. From the File menu, I selected the option 'New Answer File". This populated the 'Answer File' pane with the Configuration Pass component placeholders as shown below. This looked daunting, but remember for scripted installs we only need to worry about the WindowsPE, OfflineServicing, specialize and oobeSystem configuration passes, and likewise for sysprep only the specialize and oobeSystem passes.


And that is SIM now ready for me to add components so that I could create an unattend XML files for scripted or sysprep deliveries. At this point it was difficult to know where to begin with SIM when creating answer files, so I tried to keep in mind exactly what questions I wanted answered by the answer file. For example, from the manual installation I had to answer these,

  1. Selecting Language, Time/Currency Format & Keyboard
  2. Eula acceptance
  3. New Copy of Windows being installed (custom)
  4. Installing to disk 0
  5. User Account details
  6. Timezone
  7. Network Location

SIM doesn't tell you where to find parameters within the available components, so this is where I needed a little help from other's answer files to get started. What I had to do next was not trivial -I needed to select the correct components from the myriad of components available in the windows image pane, apply them to correct pass, and then configure the embedded settings as appropriate. After lot of trial and error, I came up with the process below. To make the instructions succinct, I'm presenting each setting value as a , ) pair. You'll get the idea. One handy feature of SIM is that if you have any problems understanding how to use any parameter, just right-click it in the properties pane and select help. The WSIM help is context sensitive and will throw you to the right place in the help file. Very useful.

So, without further adieu, below is the potted process which emerged for creating my Windows 7 scripted install unattend answer file,

  1. In the Windows Image pane, select the component x86_Microsoft-Windows-International-Core-WinPE_6.1.7600.16385_neutral, right-click and add to the WindowsPE pass. Using the Answer File and Properties panes, configure the following settings,

    InputLocale, 0809:00000809
    SystemLocale, en-GB
    UILanguage, en-US
    UserLocale, en-GB

    Note: In the above, I've configured the local settings for the United Kingdom, so you'll need to configure as appropriate for where you are in the world. On watch point though -don't change the UILanguage from en-US. In my testing, Windows setup doesn't appear to like this setting being changed, and results in all your locale and language settings being ignored.

  2. In the Windows Image pane, select the component x86_Microsoft-Windows-Setup_6.1.7600.16385_neutral, right-click and add to the WindowsPE pass. Using the Answer File and Properties panes, configure the following settings,

    UserData\AcceptEula, true
    ImageInstall\OSImage\InstallTo\DiskID, 0
    ImageInstall\OSImage\InstallTo\PartitionID, 1

    Note: Microsoft's disk and partition numbering schemes are such that Disk 0 is the first disk and Partition 1 is the first partition.

  3. In the Windows Image pane, select the component x86_Microsoft-Windows-Shell-Setup_6.1.7600.16385_neutral ,right-click and add to the oobeSystem pass. Using the Answer File and Properties panes, configure the following settings,

    TimeZone,GMT Standard Time
    OOBE\HideEulaPage,true
    OOBE\NetworkLocation,Work
    OOBE\ProtectYouPC,1

    Now right-click UserAccount\LocalAccounts and select "Insert new Local Account"
    UserAccount\LocalAccounts\Local Account\name, user
    UserAccount\LocalAccounts\Local Account\Group, Administrators
    UserAccount\LocalAccounts\Local Account[Name="user"]\password\value, userpwd

    Note: In the above I've created a new administrative account called user as part of the windows setup. The password is uninspiring -userpwd. You'll need to change this to suite how you' want your image to be setup. ProtectYourPC has three possible values: 1=Automatic Updates enabled, 2=Only Important Updates Installed, 3=Automatic Updated disabled.

  4. In the Windows Image pane, select the component x86_Microsoft-Windows-Shell-Setup_6.1.7600.16385_neutral ,right-click and add to the Specialize pass. Using the Answer File and Properties panes, configure the following settings,
    ComputerName,test1-pc

    Note: Don't worry about changing the PC name from test1-pc as we'll be changing it soon so that this XML will work nicely in Windows 7 deployments through Deployment Server.
  5. Save the XML
  6. In the Messages pane, there will be a tonne of warning triangles. These are informational messages (or should be!) letting you know that lots of component options have been left unconfigured, and hence won't be explicitly saved into the file.

At this point, I always find it rewarding to view the XML. On my system, double-clicking always throws up IE or FrontPage, so right-click and open in the world's best editor -Notepad.




These settings tags refer to the specific configuration passes we want to configure. And within these tags, we see the components and then the parameter value pairs within their own distinctive tags. As we saw when creating our settings with SIM, some settings can be nested down a few layers, and we see this too with nested tags in the XML.

There is only one change we need in this XML to make is suitable for Deployment Server -we want the computer name to be generic. In notepad, find the tag in the specialize pass at the end of the XML. Change test1-pc to %COMPNAME% and save.

Next, in Deployment Server I created a scripted Install job "Windows 7 Scripted Install", and added to it a "Scripted OS Install" task with the following setup,

  1. Scripted Installation for Operating System (First Screen)
    From the choice of Linux and Windows, I selected "Windows" (of course...), and clicked "Next".
  2. Scripted Installation for Operating System (Second Screen)
    Here I selected the OS version as "Windows 7 Enterprise", with an install Language as "English". For the automation environment, I selected the WinPE option (as tests using Linux automation all failed).
  3. Installation Source Files.
    Here I had to "Add New", as I didn't have a Windows 7 Enterprise option already available.

    And then clicked 'OK' and waited for the files to copy.

  4. Partition and Format Disk

    Left at the default to use Diskpart, and clicked "Next".

  5. Preparation of XML answer file
    Copy the scripted install XML created above to your server, and change path to the location of your new XML file,

    And then I clicked "Next"

  6. Scripted Install OS Commands
    This screen just shows the command-line which will be used to initiate the Windows setup and install the DAgent. As you can see, the XML referenced isn't from our location specified earlier, but is actually an xml file on the express share's temp folder. This is fine, our XML file will undergo a token replacement process and copied to the express share temp folder as part of the scripted install workflow.

    At this point I did wonder how the heck this DAgent.msi was going to get pushed to the C:\ Drive. A quick investigation of the source tree in the Deploy folder on the express share, revealed that Windows 7 supports the $OEM$ folder structure just like XP (at least for the simple $1 and $$ references). The then the agent is installed from the setupcomplete.cmd which the install source places in the C:\Windows\Setup\Scripts folder (not cmdlines.txt as the Wizard suggests!).

    Clicked "Next" to proceed...

  7. Deployment Agent Settings
    The defaults will be fine. Clicked Next to continue.
  8. Scripted Install Summary
    This screen allows you to do a quick sanity check. Clicked 'Finish'

I then dropped the resulting job on my target computer, and then sat back and relaxed. Windows 7 will proceeded to install completely unattended. Nice.

3. Find out how to Sysprep Windows 7

Good news -sysprep is still called sysprep! If you want to image Windows computers, sysprep is the tool you want. Many people avoid using sysprep -probably because Altiris have tried hard to implement an imaging process which does not require it. As a result, sysprep is a headache many Altiris administrators out there simply because they've have never had to deal with it to image computers. Sysprep is however the simplest way to introduce hardware independence and post-deployment tweaks into your imaging, so I always recommend people start playing with sysprep as soon as they can.

It turns out that making a sysprep'd image with Deployment Server is now so easy, it's laughable as Windows 7 has sysprep built in. It's just a couple clicks more to create a imaging job with sysprep, than it is to create a standard disk image upload job. And once we've got a sysprep image uploaded, we can deploy it with a variety of customisations through a sysprep.xml file.


The steps I used for this were as follows,

  1. Created a new Job, and called it "Create Windows 7 Sysprep Image"
  2. Added a "Create Disk Image" task, setting the file path to ".\Images\Windows\Win7_Sysprep.img"
  3. In the sysprep settings frame, checked the box "Prepare using sysprep" , and select the OS as "Windows 7 Enterprise"
  4. In the Preboot environment drop-down, selected the WinPE boot option.

  5. And clicked "Finish"

Then I just dragged this job onto my recently installed Windows 7 computer, after which it syspreped and then automatically uploaded the sysprep'd disk image. I should point out at this stage that during sysprep the generalize configuration pass is invoked. We don't need to explicitly worry about this though, as it's all fairly transparent.

It took perhaps 20 minutes for sysprep to completed and with PXE booting enabled the computer rebooted at the end and automatically started uploading the image. I was fairly impressed (or probably more accurately, relieved).
At this point I really felt I was on a roll, and that was about to continue. Deploying the Sysprep image is very easy -in many situations you don't even need to create your own sysprep answer file! Just create a deploy job for your sysprep image in the Deployment Console and configure it to use the default answer file.

When you do this, your distribute disk image task should look as follows,

And if you were to take a look at the advanced settings, you'd see that Deployment Server's default answer file is going to be used.

And that's pretty much it. You can now deploy your sysprep images to your heart's content. And no BCDEDIT scripts in sight. Good huh?

4. Find out how to Tweak Sysprep Images on Delivery

To tweak the sysprep images on delivery, we need to turn once again to the configuration passes and that XML. The good news continued -creating a Windows 7 sysprep answer file is very, very simple. If you remember, we only needed to worry about two configuration passes -the specialize and oobesystem passes. This is because Windows has already been installed, so the WindowsPE pass which controls the initial install process from the WIM file isn't available, and ditto for the OfflineServicing pass too.

So, I once again returned to the Windows System Installation Manager. I opened up a blank answer file, and the final process I came up with is as follows,

  1. In the Windows Image pane, select the component x86_Microsoft-Windows-Shell-Setup_6.1.7600.16385_neutral ,right-click and add to the oobeSystem pass. Using the Answer File and Properties panes, configure the following settings,

    TimeZone,GMT Standard Time
    OOBE\HideEulaPage,true
    OOBE\NetworkLocation,Work
    OOBE\ProtectYouPC,1
    SkipMachineOOBE, true

    Note: SkipMachineOOBE allows us to avoid creating a new user account as part of the sysprep delivery. We don't want to create another account -our local admin was already configured in the scripted install and is in our sysprep image.

  2. In the Windows Image pane, select the component x86_Microsoft-Windows-International-Core_6.1.7600.16385_neutral, right-click and add to the oobeSystem pass. Using the Answer File and Properties panes, configure the following settings,

    InputLocale, 0809:00000809
    SystemLocale, en-GB
    UILanguage, en-US
    UserLocale, en-GB

    Note: In the above, I've again configured the local settings for the United Kingdom, so you'll need to configure as appropriate for where you are in the world.

  3. In the Windows Image pane, select the component x86_Microsoft-Windows-Shell-Setup_6.1.7600.16385_neutral ,right-click and add to the Specialize pass. Using the Answer File and Properties panes, configure the following settings,

    ComputerName,test1-pc

    Note: Don't worry about hard-coding the PC name -as before, you'll change this to %COMPNAME% later so it will work nicely in Windows 7 deployments through Deployment Server.

  4. Save the XML





In order to get this XML ready for use with Deployment Server, I again had to change the value to %COMPNAME% as before. Feel free to use the above as a basis for your own custom sysprep deployments.

Before we leave sysprep delivery, I would be amiss if I did not mention a few things.

  1. Domain Joins
    Joining computers to the domain from Windows Setup can be a little unreliable. I've seen some sites where domain joins are flawless, and others where the unreliability is a true pain. I suspect that domain settings in DHCP play a role, and I am told the underlying reason for this is that the code used for the domain join in Windows Setup is more fragile than used in the main OS. To get around these problems, I tend to leave domain joins to an Deployment Server configuration task -this never seems to fail.
  2. The Network Location Bug
    Syspreped images suffer from a Network Location bug, and this has been around in various guises since Vista was released. Microsoft have released a hotfix under KB2028749 which resolves this. Thanks to striskle for letting me know about this one.
  3. Sysprep vs Scripted Install
    Image delivery is always faster than a scripted install, and I tend to recommend scripted installations for image builds rather than for deployments. As a simple example of time, I've seen images which take 6 hours to build from scratch using a completely automated build process. In contract, the image which pops out of this build process takes 40 minutes to deploy. So, even though the added step of taking an image might seem a pain, it can save you a huge amount of time.
  4. Windows 7 and HAL
    No more black screens! Windows 7 is designed to autodetect the HAL and can change this on the fly now in Windows setup. One less headache for the IT Administrator!

Summary

Using the above processes as a basis, I was finally able to start building an image process which had parity with our XP build & deployment systems already in place. I could then hand over these basic jobs to the software packagers, so they could then get on with the real work of testing all our XP packages on Windows 7. Hopefully they won't hit too many problems, but heck I hope there are a few -it shouldn't be too easy after all.

But we're on the road to Windows 7, and frankly its not looking quite so bad as we first thought. Thankfully.

Before I leave this blog to gather dust, a few brief points,

  1. Domain Joins
    Joining computers to the domain from Windows Setup can be a little unreliable. At least for me. I've seen some sites where domain joins are flawless, and others where the unreliability is a true pain. I suspect that domain settings as delivered by DHCP play a role, but I need to dig deeper to figure this out. I am told the underlying reason for this is that the code used for the domain join in Windows Setup is more fragile than used in the main OS. If you experience domain join difficulties, try leave domain joins to a Deployment Server configuration task -this never seems to fail.
  2. The Network Location Bug
    Syspreped images suffer from a Network Location bug, and this has been around in various guises since Vista was released. Microsoft have released a hotfix under KB2028749 which resolves this. Thanks to striskle for letting me know about this one.
  3. Sysprep vs Scripted Install
    Image delivery is always faster than a scripted install, and I tend to recommend scripted installations for image builds rather than for deployments. As a simple example of time, I've seen images which take 6 hours to build from scratch using a completely automated build process. In contrast, the image which pops out of this build process takes 40 minutes to deploy. So, even though the added step of taking an image might seem a pain, it can save you a huge amount of time.
For More Details:

http://www.symantec.com/connect/blogs/windows7-untangling-scripted-installs-sysprep-and-configuration-passes