The Deployment Bunny

OS Deployment, Virtualization, Microsoft based Infrastructure…

  • Archives

  • Meta

WIM2VHD using a PowerShell script (plus 2 more, WIMINFO and MakeVM-Diff scripts)

Posted by Mikael Nystrom on May 7, 2012

The Story

When using Hyper-V you need a VHD, so the correct way for creating a VHD is to use MDT 2012 (Lite Touch) and I do that for my production servers, but in some cases you do not have the deployment solution in a pocket, you just need the standard wim file converted into a bootable VHD file so you can use that as a template. Then when you have the template created you also need to be able to build new machines using that reference image and clicking in the UI is fun, for a while…

When Hyper-V was new Microsoft (a former MVP) created a VB script called WIM2VHD that I used all the time, a very nice script I think, but in Windows 8 we have all that stuff inside the OS and we do have a much stronger story in PowerShell

To be honest, I did create these script a while back, but today I was running a Windows Server 8 BETA Load fest and I used these scripts to build a bunch of demo machines, 2 minutes later our own staff was standing in line begging to get the scripts, so I gave them away but at the same time I thought you should also have access to them

The Solution

First of all, I’m not really a PowerShell “whiz kid”, I used to be the old “batch file” guy, but I’m converting (A nice thing is to have Niklas Goude that just happens to be an MVP in PowerShell in the organization).
Second, we need a couple of script. We need something to take a look inside a WIM, something that create a VHDX and applies the WIM to that VHDX and the last one, something that can build VMs using that ref image.

Script number 1: (wiminfo.ps1)

This script will mount the ISO image and read the content of the WIM file, this way we know what index we shall use.

Param
(
[parameter(mandatory=$true,HelpMessage=”Please, I need the ISO image name, ok?”)][ValidateNotNullOrEmpty()]$ISO
)
Mount-DiskImage -ImagePath $ISO
$ISOImage = Get-DiskImage -ImagePath $ISO | Get-Volume
$ISODrive = [string]$ISOImage.DriveLetter+”:”
Get-WindowsImage -ImagePath $ISODrive\sources\install.wim
Dismount-DiskImage -ImagePath $ISO

 

Script number 2: (wim2vhd.ps1)

This script will mount an ISO image, create the VHDx file, applies the WIM file to the VHDx file and then creates the BCD and dismounts everything.

Param

(

[parameter(mandatory=$true,HelpMessage=”Please, I need the ISO image name, ok?”)][ValidateNotNullOrEmpty()]$ISO,

[parameter(mandatory=$true,HelpMessage=”Please, I need the VHDx image name, ok?”)][ValidateNotNullOrEmpty()]$VHDx,

[parameter(mandatory=$true,HelpMessage=”Please, I need the Index number in the Wim, ok?”)][ValidateNotNullOrEmpty()]$Index,

[parameter(mandatory=$true,HelpMessage=”Please, I need the Size of your VHDx, ok?”)][ValidateNotNullOrEmpty()]$SizeGB

)

 

Mount-DiskImage -ImagePath $ISO

$ISOImage = Get-DiskImage -ImagePath $ISO | Get-Volume

$ISODrive = [string]$ISOImage.DriveLetter+”:”

 

$VMDisk01 = New-VHD –Path $VHDX -SizeBytes $SizeGB

Mount-DiskImage -ImagePath $VHDX

$VHDDisk = Get-DiskImage -ImagePath $VHDx | Get-Disk

$VHDDiskNumber = [string]$VHDDisk.Number

 

Initialize-Disk -Number $VHDDiskNumber -PartitionStyle MBR

$VHDDrive = New-Partition -DiskNumber $VHDDiskNumber -UseMaximumSize -AssignDriveLetter -IsActive | Format-Volume -Confirm:$false

$VHDVolume = [string]$VHDDrive.DriveLetter+”:”

 

dism.exe /apply-Image /ImageFile:$ISODrive\Sources\install.wim /index:$Index /ApplyDir:$VHDVolume\

 

BCDBoot.exe $VHDVolume\Windows /s $VHDVolume /f BIOS

 

Dismount-DiskImage -ImagePath $ISO

Dismount-DiskImage -ImagePath $VHDX

 

Script number 3: (MakeVM-Diff.ps1)

This script will create a VM in Hyper-V based on that VHDx file as a differencing file. It supports a bunch of command line parameters

Param

(

[parameter(mandatory=$true,HelpMessage=”Please, provide a name.”)][ValidateNotNullOrEmpty()]$VMName,

[parameter(mandatory=$true,HelpMessage=”Please, provide a location.”)][ValidateNotNullOrEmpty()]$VMBaseLocation,

[parameter(mandatory=$true,HelpMessage=”Please, provide the amount of starting memory.”)][ValidateNotNullOrEmpty()]$VMMemory,

[parameter(mandatory=$true,HelpMessage=”Please, provide a RefDisk.”)][ValidateNotNullOrEmpty()]$VMRefDisk,

[parameter(mandatory=$true,HelpMessage=”Please, provide a Switch.”)][ValidateNotNullOrEmpty()]$VMNetwork

)

 

$VMLocation = New-Item -Path “$VMBaseLocation\$VMName” -ItemType Directory -Force

$VMDiskLocation = New-Item -Path “$VMLocation\Virtual Hard Disks” -ItemType Directory -Force

$VMDisk01 = New-VHD –Path $VMDiskLocation\$VMName-OSDisk.vhdx -Differencing –ParentPath $VMRefDisk

$VMDisk02 = New-VHD –Path $VMDiskLocation\$VMName-DataDisk01.vhdx -SizeBytes 60GB

 

$VM = New-VM –Name $VMname –MemoryStartupBytes $VMMemory –VHDPath $VMDisk01.path -SwitchName $VMNetwork -Path $VMBaseLocation

Add-VMHardDiskDrive -VM $VM -Path $VMDisk02.path –ControllerType SCSI -ControllerNumber 0

Set-VM -VM $VM -DynamicMemory

 

Summary:

Now you have a solution that is capable of building a complete environment on a Windows Server 8 machine and a ISO image pretty fast.

Download Script

/mike

5 Responses to “WIM2VHD using a PowerShell script (plus 2 more, WIMINFO and MakeVM-Diff scripts)”

  1. Beatit said

    Thank you very much for releasing this script.

  2. […] For more info, please refer to his original post: WIM2VHD using a PowerShell script (plus 2 more, WIMINFO and MakeVM-Diff scripts) […]

  3. […] have loaned some code from Mikael Nyström (Deployment Bunny) but had to rewrite a little to make it work with the workflow […]

  4. […] should be created using Microsoft Deployment Toolkit 2012 Update 1. But if you are lazy you can use WIM2VHD.PS1. You might also need WIMINFO.PS1 to find out the index number of the WIM. So now you have a […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: