Saturday, November 2, 2013

Creating Data VHD using PowerShell

 
If you haven’t used PowerShell automation for Hyper-V, it is time to try it. This is a short blog that solved couple of tricky and annoying issues that blocks automation. Creating a data VHD (or VHDX) using PowerShell is tricky, requires connecting a few cmdlets together. An annoying popup “You need to format the disk in drive D: before you can use it.” breaks automation. Proposed solution solves this problem.
 
In Windows 8.1/Windows Server 2012 R2, Mounting a VHD, sometimes the drive letter does not show up. The code fragment below has a workaround to solve this as well.

 

Create the VHD file

VHD file can be used as a generic container to store file collection. The file collection can be hierarchical (i.e.) like a disk drive. Hence it can be used as a packaging mechanism, easy to transfer single file. This also comes in handy with automation. A typical automation scenario is: Create a VHD file, copy the file content to this VHD file, and make this VHD available to the VM as an additional disk. This technique is used in multi. 
 
New-VHD cmdlet creates a VHD file, but the created file is not formatted (hence no file system). Before the disk is formatted, it has to be initialized and a partition should be created. After I figured how to format the disk, I started to hit the following message box randomly.
 
 
I tried different things with no luck. Finally, I reached out to Senthil Rajaram, Senior Program Manager at Microsoft. He gave me the brilliant code fragment that solved this annoying popup.
 
 
# Creates a data VHD file (non OS VHD file)
# VHDPath – Full path to a VHD file
# Size – size of the VHD file to create. This creates a dynamic VHD,
#    (i.e) the VHD file is not expanded to full size
 
function CreateVHD ($VHDPath, $Size)
{
  $drive = (New-VHD -path $vhdpath -SizeBytes $size -Dynamic   | `
              Mount-VHD -Passthru |  `
              get-disk -number {$_.DiskNumber} | `
              Initialize-Disk -PartitionStyle MBR -PassThru | `
              New-Partition -UseMaximumSize -AssignDriveLetter:$False -MbrType IFS | `
              Format-Volume -Confirm:$false -FileSystem NTFS -force | `
              get-partition | `
              Add-PartitionAccessPath -AssignDriveLetter -PassThru | `
              get-volume).DriveLetter
 
    Dismount-VHD $VHDPath
}
 
 
Note: In the above code sample, the expression to create VHD and format is a single pipeline, but spread over multiple lines for readability. If a line ends with the character “`”, it tells PowerShell that the following line is a continuation of the current line.
 

MountVHD and DismountVHD

To access and manipulate a VHD file, it has to be mounted. Use the Mount-VHD cmdlet to mount the VHD file. By default it assigns a drive letter to the mounted VHD. (i.e.) You can access the VHD file like a disk drive. I wrote a simple helper function “MountVHD”, this takes the path to the VHD file and returns the path where the file is mounted.
 
 
# Mount the VHD file so that it can be accessed like a drive
# $VHDPath points to VHD file (full path)
# Returns path to the mounted VHD (e.g.) D:\
 
function MountVHD ($VHDPath)
{
    Mount-VHD $VHDPath
    $drive = (Get-DiskImage -ImagePath $VHDPath | `
                 Get-Disk | `
                 Get-Partition).DriveLetter
    "$($drive):\"
    Get-PSDrive | Out-Null # Work around. some times the drive is not mounted
}
 
# Dismount an already mounted VHD file
# After dismount the drive is not accessible.
 
function DismountVHD ($VHDPath)
{
    Dismount-VHD $VHDPath
}
 
 

Sample Usage

Now that the functions are defined, invoke the function to create a VHD file, copy some sample files.
 
 
# Create a VHDX file c:\temp\x.vhdx
CreateVHD -VHDPath "c:\temp\x.vhdx" -Size 10GB
 
# Mount the VHD, copy c:\data to it and finally dismount it.
$path = MountVHD -VHDPath 'c:\temp\x.vhdx'
 
Copy 'c:\data' $path -Recurse
 
DismountVHD -VHDPath 'c:\temp\x.vhdx'
 
 
Explore & Enjoy!
/Siva

7 comments:

  1. Hi,

    have this working great and uploading to Azure, can we have a step by step report then email that report when the task ends?
    Thanks James.

    ReplyDelete


  2. This is an awesome post.Really very informative and creative contents. These concept is a good way to enhance the knowledge.I like it and help me to article very well.Thank you for this brief explanation and very nice information.Well, got a good knowledge.
    DedicatedHosting4u.com

    ReplyDelete
  3. I have to say, this was one of the best posts on this topic; clear and explained a few points I could not find elsewhere. Thank you.

    ReplyDelete
  4. You need to get familiar with this info to resolve this question.

    ReplyDelete
  5. Very good article post this is all about the mount VHD very well explain each and everything step by step guide thanks for this important blog Geek squad tech support

    ReplyDelete