Friday, January 11, 2013

Automating Image Building with MDT 2012u1 and Hyper-V

Happy New Year's everyone (all 6 of you reading this)!  Been a very busy month with the holiday season and I haven't had much time to post anything new, too busy playing with all the cool tech toys.  After a comment I made on the Microsoft TechNet Forum for MDT (http://social.technet.microsoft.com/Forums/en-US/mdt/threads), I thought I should write this post up.  I'll show you how I've completely automated regular Image builds using MDT 2012u1 and Hyper-V.

Setting up a 'Build' VM on Hyper-V

The first step is to create a new Virtual Machine on Hyper-V.  I called my first one 'BUILD-W8x64'. Give it all the normal settings and ensure you add a Hard Drive of an appropriate size for your Image and all the configuration and applications you want to capture.  You can either select a Dynamic MAC or a Static.  If you allow Dynamic, you just need to start and stop the machine once so that Hyper-V assigns it a MAC address.  Note the MAC address of your new VM for use later in MDT.  Lastly, assign the VM the MDT Boot Media.  Once you've done this, create a Snapshot of the VM and call it "Blank" or something that indicates to you there is nothing on the VHD(x).

Configure Bootstrap.ini

To make things fully automated, you don't want MDT prompting for credentials to connect to the Deployment Share.  I didn't like the idea of using a domain account for this with privileges, so I created a local account on the Deployment Share's server, then updated Bootstrap.ini:

[Settings]
Priority=Default

[Default]
SkipBDDWelcome=YES
UserDomain=MDTServer
UserID=MDTUser
UserPassword=P@ssw0rd!

Once you've done this, make sure you re-generate your boot images and copy it to what the VM is pointed to.

Configure CustomSettings.ini

Then you'll need to update your CustomSettings.ini so that you skip all screens, set what needs to be set, and have the MAC address used as the trigger to pick the right Task Sequence ID (W8X64-BUILD in my example):

[Settings]
Priority=MACAddress,Default

[Default]
EventService=http://MDTserver:9800

[00:00:00:00:00:00]
TaskSequenceID=W8X64-BUILD
OSInstall=Y
SLShare=%DeployRoot%\Logs
WsusServer=http://MDTserver
SkipAppsOnUpgrade=YES
SkipDeploymentType=YES
SkipComputerName=YES
osdcomputername=*
SkipDomainMembership=YES
JoinWorkgroup=MDTBUILT
SkipUserData=YES
SkipComputerBackup=YES
SkipProductKey=YES
SkipPackageDisplay=YES
SkipLocaleSelection=YES
  UserLocale=en-us
  InputLocale=en-us
  KeyboardLocale=en-us
SkipTimeZone=YES
  TimeZone=15
  TimeZoneName=Pacific Standard Time
SkipApplications=YES
SkipAdminPassword=YES
  AdminPassword=P@ssw0rd!
SkipCapture=YES
  DoCapture=YES
  ComputerBackupLocation=%DeployRoot%\Captures\W8X64-BUILD
SkipRoles=YES
SkipBitLocker=YES
SkipSummary=YES
SkipFinalSummary=YES
FinishAction=SHUTDOWN

Some of the settings you'll obviously need to adjust to your own (such as Locale, Time Zone, and Password).

Configure the Task Sequence

For this process, I took a Standard Client Task Sequence, picked my Operating System and other settings.  I customized it with my application installs and custom configuration like I would a normal MDT Task Sequence (where the "Install Applications" task is placed by default between the Pre and Post-WSUS tasks).

The last task in my set of custom steps is a to "Run PowerShell Script" and I call BackupFileName.ps1, which is stored in %DeployRoot%\Scripts.

BackupFileName.ps1
$strDate = Get-Date -format yyyy\-MM\-dd\-HH\-mm\-ss
$TSEnv:BackupFile = $TSEnv:TaskSequenceID + "_" + $TSEnv:TaskSequenceVersion + "_" + $strDate + ".wim"

This simply gets the date in a format I wanted, gets the TaskSequenceID and Version, then appends it all together to create the new name of the .WIM file.  If you don't do this, MDT will default the name to the Task Sequence ID and if the file already exists, it will throw an error.  This also allows me the luxury of knowing what version was built, and when, and to archive builds if needed.

Warning:  Doing this can consume a LOT of space, especially if you are building many images.  Make sure you have enough space and have a plan to clean up or archive WIMs you no longer want or need.

Task Scheduler

The last piece in all this is getting it to run automatically.  If you've configured everything correctly thus far, simply starting the VM should result in a completed WIM in the capture folder and the VM off again.  We want to schedule the Revert and Start steps.

Inside Task Scheduler, create a new Task.  Name it whatever you want, but make sure that "Run whether user is logged on or not" is chosen.  Also select "Run with highest privileges".  Set your Trigger to run when and how often you want.  Mine is set to run at 1:00 AM every 16th of the month (to ensure that I get Patch Tuesday WSUS updates in each image build).

The Action is "Start a program" with "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" as the path.  You'll need to pass arguments, also: "-noninteractive -nologo C:\MDT\Automate-W8.ps1".  For this script, I utilized the PowerShell Management Library for Hyper-V.  It's likely that you can update this script on Server 2012 and not use this additional module, but this is the route I took on a Server 2008 R2 machine.

Automate-W8.ps1
Import-Module 'C:\Program Files\modules\HyperV\HyperV.psd1'
$VM = "BUILD-W8x64"
Get-VMSnapshot $VM | Restore-VMSnapshot -Force
Start-VM $VM

My PowerShell is not as good as I'd like, but this let me get the Snapshot, Revert, then Start the VM.  I should update this script to take $VM as a parameter, I just haven't yet. : )

Summary

If you've done everything right, your server will now automatically start your Build VM, crank out a new WIM (with new monthly WSUS updates!!) and save it out with version information, on a schedule.  That's what I call automation!

-DCtheGeek

1 comment:

  1. After you have configured everything and you start the Hyper-V VM, How do you make it boot to the MDT boot ISO without the 'Press any key to boot from CD or DVD' message?

    ReplyDelete