Monday 6 February 2012

Script to create VHD, populate it from WIM file and then set the boot from VHD option

I've been working in my lab environment at home on the Private Cloud stuff and I tend to use Oracle's VirtualBox product. I decided that I wanted to change one of my machines to be a physical box though as I'm somewhat resource constrained. Normally I use the VBoxmanage clonehd to clone my Sysprepped base machine; however that's not going to work in the physical world. So I fired up my BaseVM using a Win 2008 R2 setup DVD, imagex'd the drive and transferred my new WIM file out to my host machine.

I then wrote the following script which creates the VHD file using diskpart, populates it using imagex, detaches the disk and then optionally adds the VHD file to the boot from VHD option on Win7 / 2008 R2. This allows me to fire up a new machine fairly quickly on either physical or virtual hardware. Given the VHD nature of the file it's also even easier to switch to different hypervisors such as Hyper-V.

Note1: The credit for some of the script belongs to Dan Stolts from the following article: http://blogs.technet.com/b/danstolts/archive/2011/03/29/how-to-automatically-create-bcdedit-data-for-a-boot2vhd-file-on-your-windows-7-or-windows-server-2008-r2-machine.aspx
Note2: You will also need imagex.exe either in the same location as the script or in a pathed location.
Note3: Remember to specify your variables in the variables section.

------SAVE BELOW AS A .CMD/.BAT FILE-------------

@ECHO OFF
REM This batch file will perform the following actions
REM
REM Create a virtual disk (VHD format)with the name of the first parameter
REM with a size in GB of the second parameter
REM
REM It will then attach the disk to the local machine and apply the image from the WIM file specified
REM It will then detach the disk
REM
REM If the optional YES 3rd parameter is set it will then add the VHD as a boot option to the local machine
cls
REM Verify Parameters are set correctly
REM ===================================
if "%1" == "" (
    goto :Usage
)
if "%2" == "" (
    goto :Usage
)
if "%3" == "YES" (
    goto :Continue
)
if "%3" == "yes" (
    goto :Continue
)
if "%3" == "Yes" (
    goto :Continue
)
if "%3" == "" (
    goto :Continue
)
goto Usage
:Continue
REM Variables Section
REM =================
set VHD=%1
set Size=%2
set WimFile=C:\VMs\BaseVM.wim
set ImageIndex=1
set TargetDrive=C:
set VHDFolder=\VMs
if exist %TargetDrive%%VHDFolder%\%1.vhd goto ErrorExist
REM Diskpart Section
REM ================
ECHO Creating VHD file %TargetDrive%%VHDFolder%\%1.vhd with a maximum size of %Size%GB
IF EXIST Diskpart-Create.txt DEL Diskpart-Create.txt
ECHO create vdisk file=%TargetDrive%%VHDFolder%\%1.vhd maximum=%size0 type=expandable > Diskpart-create.txt
ECHO select vdisk file=%TargetDrive%%VHDFolder%\%1.vhd>> Diskpart-create.txt
ECHO attach vdisk >> Diskpart-create.txt
ECHO create partition primary >> Diskpart-create.txt
ECHO format quick FS=NTFS label=OS >> Diskpart-create.txt
ECHO assign letter=v >> Diskpart-create.txt
ECHO active >> Diskpart-create.txt
ECHO exit >> Diskpart-create.txt
diskpart /s Diskpart-create.txt
REM Imagex Section
REM ==============
ECHO Applying image
imagex /apply %WimFile% %ImageIndex% V:
bcdboot V:\Windows /s V:

REM Detach VHD
REM ==========
ECHO Detaching Image
IF EXIST Diskpart-Detach.txt DEL Diskpart-Detach.txt
ECHO select vdisk file=%TargetDrive%%VHDFolder%\%1.vhd > Diskpart-Detach.txt
ECHO detach vdisk >> Diskpart-Detach.txt
diskpart /s Diskpart-Detach.txt

REM Add VHD to Boot Menu
REM ====================

if "%3" == "YES" (
    goto :Boot2VHD
)
if "%3" == "yes" (
    goto :Boot2VHD
)
if "%3" == "Yes" (
    goto :Boot2VHD
)
if "%3" == "" (
    goto :End
)
goto Usage

:Boot2VHD
set VHDFILENAME=%1
set VHDDESC="Boot from VHD"
@echo VHDFileName=%1
@echo Creating VHD boot entry for %VHDDESC%....
cmd /c " bcdedit /copy {current} /d %VHDDESC% " > VHDGUID.txt
FOR /F "tokens=7 delims=. " %%A in (VHDGUID.txt) DO set GUID=%%A
@echo VHD boot entry GUID = %GUID%
set BCDFName=%VHDFolder%\%1.vhd
@echo Configuring VHD boot entry....
@echo setting Device... vhd=[locate]%BCDFName%
bcdedit /set %GUID% device vhd=[locate]%BCDFName%
@echo setting OSDevice... vhd=[locate]%BCDFName%
bcdedit /set %GUID% osdevice vhd=[locate]%BCDFName%
bcdedit /set %GUID% detecthal on
bcdedit /default %GUID%
Goto End
:ErrorExist
ECHO The file %TargetDrive%%VHDFolder%\%1.vhd already exists. Please delete before recreating
goto End
:Usage
ECHO Please specify both {Name} and {Size in GB} parameters
ECHO.
ECHO Optional 3rd parameter: Specify YES to add Boot2VHD feature on local machine
ECHO.
ECHO E.G. CreateVHD.cmd Win2008R2 100 YES
:End
if exist Diskpart-create.txt del Diskpart-create.txt
if exist Diskpart-detach.txt del Diskpart-detach.txt
if exist VHDGUID.txt del VHDGUID.txt

No comments:

Post a Comment