Showing posts with label VHD. Show all posts
Showing posts with label VHD. Show all posts

Tuesday, March 26, 2013

Converting VHDX VHD and back without Hyper-V

So.  I am really rehashing another script that I already did a few posts ago.

If you look back here: http://itproctology.blogspot.com/2013/01/powershell-for-reducing-size-of-vhd.html

If you being with a virtual disk that is a VHD.

And you alter this one line:

$newVhdPath = $orgvhd.ImagePath.Split(".")[0] + $partNum +"New." + "vhdx"

You end up with a VHDX instead of a VHD.  Go backward, flip it around. 

Server 2012 / Windows 8 have some built in assumptions based on the extension. You get the VHD format that the extension defines. That is why you just cannot modify the file extension.

 

What got me started on this?  Well, my original post was because I was annoyed with certain cmdlets being only bound to the existence of the Hyper-V virtual machine management service (having Hyper-V installed).  Since the OS storage layer knows about these virtual disks, why can’t I natively manipulate them?

And then this post came through the Hyper-V forums: http://social.technet.microsoft.com/Forums/en-US/winserverhyperv/thread/51984c52-cc69-459f-8999-6ca186d48931

Again, folks with my same original complaint.  It requires Hyper-V.  Ugh.

 

So. Let’s make this script a one trick pony.  And ONLY let it convert virtual disk formats.

Now, that said.  This is a hack folks.  I did it because I can, and the tools are built in to the OS.  DISM does not convert disks or volumes, it converts partitions.  So you get one virtual disk per partition. (Frankly, who partitions disks anymore anyway?)

 

# Server 2012 / Windows 8 VHD / VHDX converter.  Using DISM.
# Prototyped on Server 2012 not running Hyper-V
# This utilizes PowerShell v3 and cmdlets from Server 2012 / Windows 8 - it will not run on any older OS.
# Copy write – Brian Ehlert

# Ask the path of the VHD and test it
Do {
    $imagePath = Read-Host "Please enter the full path to your VHD.  i.e. D:\VMs\MyVhd.vhd "
} until ((Test-Path -Path $imagePath ) -eq $true)  # Mount the VHD that will be getting resized

$orgVhd = Mount-DiskImage -ImagePath $imagePath -PassThru
$orgVhd = Get-DiskImage -ImagePath $orgVhd.ImagePath  # Get the partitions
$orgParts = Get-Partition -DiskNumber $orgVhd.Number  # Use DISM command line to capture the VHD one WIM file. Each partition with a different name.
$wimName = ($orgvhd.ImagePath.Split(".")[0] + ".wim") 
foreach ($part in $orgParts) {
    if ($part.Size -gt 524288000){ # skip the partition if it is less than 500MB, most likely there is no OS or it is the System Reserved partition.
        $capDir = $part.DriveLetter + ":\"
        $partNum = $part.PartitionNumber
        "Be patient, this could take a long time"
        & dism /capture-image /ImageFile:$wimName /CaptureDir:$capDir /Name:$partNum
    }
}
# dismount the VHD that was just captured
Dismount-DiskImage -ImagePath $orgvhd.ImagePath

# Change the extension
Switch ($orgvhd.ImagePath.Split(".")[1]){
    vhd {$diskFormat = "vhdx"}
    vhdx {$diskFormat = "vhd"}
}

foreach ($part in $orgParts)
    {
    if ($part.Size -gt 367001600){ # skip the partition if it is less than 350MB.
        $capDir = $part.DriveLetter + ":\"
        $partNum = $part.PartitionNumber
        $newVhdPath = $orgvhd.ImagePath.Split(".")[0] + $partNum + "." + $diskFormat           
        $newSize = (([uint64]$orgVhd.Size) /1024 /1024)
        $diskPart = @"
        create vdisk file="$newVhdPath" type=expandable maximum=$newSize
        select vdisk file="$newVhdPath"
        attach vdisk
        create partition primary
        active
        format fs=ntfs quick
        assign
"@
        $diskPart | diskpart
        $newVhd = Get-DiskImage -ImagePath $newvhdPath
        $newVhdDrive = (Get-Partition -DiskNumber $newVhd.Number)
        $newVhdLetter = (Get-Partition -DiskNumber $newVhd.Number).DriveLetter + ":"         
        "Be patient, this could take a long time"
        & dism /apply-image /ImageFile:$wimName /ApplyDir:$newVhdLetter /Name:$partNum
        New-PSDrive -PSProvider FileSystem -Name $newVhdDrive.DriveLetter -root ($newVhdDrive.DriveLetter + ":\") # Make the new volume known to your PowerShell session
        # if \Windows then assume a boot volume and create the BCD
        if ((Test-Path -Path ($newVhdLetter + "\Windows") -PathType Container) -eq $true)
        {
            bcdboot $newVhdLetter\Windows /s $newVhdLetter
        }
         Remove-PSDrive -PSProvider FileSystem -Name $newVhdDrive.DriveLetter
        Start-Sleep 10  # Settling time
        Dismount-DiskImage -ImagePath $newVhdPath
    }
}

Friday, January 25, 2013

PowerShell for reducing the size of a VHD

Recently I have gotten myself into a situation where a VHD that I created was too large for a situation.  And as many of us know, there are tools to make VHDs smaller, only larger. 
In my case, this was an important VM to the testing that I was doing, I had absolutely no desire to build a new one.  I just wanted my VHD to be smaller so I could use it for the test I intended.
Now, since the VHD has been around we have been telling folks in the forums that there is no programmatic way to reduce the size of a VHD.  There have been lots of opinions about this, but it isn’t just a case or truncating a binary file.

The problem becomes difficult because you have no idea how the OS in that VHD has laid data down into that VHD.  Are there files way out at the far end, which would be corrupted if you simply chopped it off?  Does your program have the right to go looking and figure that out and expose my data?  If there is data out there, what should be done with it to make sure the OS that sues the VHD can actually find it – it is not as easy as moving that file, it could be a system file.  And there is always the disk layout that must be honored, sectors, blocks, etc are part of how that VHD is made.
So, what have we been telling folks that get into this situation – use disk imaging software to create an image and then apply that to a new VHD of the proper size.

I decided – lets script that.   This way I can answer a couple questions and pay attention to other things.

I use diskpart and DISM.  DISM is built in to Windows 8 / Server 2012.  And so is DiskPart.  Without the full Hyper-V Role there is no way to create a VHD using PowerShell.  Go figure.

* Disclaimer – I have only tried this with VMs that contain Server 2008 or newer.  Older than that will not have a BCD, but the script will make one.

Here is my entire script, hopefully you can follow my comments.

# Server 2012 / Windows 8 VHD resizer.  Using DISM.
# Prototyped on Server 2012 not running Hyper-V
# This utilizes PowerShell v3 and cmdlets from Server 2012 / Windows 8 - it will not run on any older OS.
# Copy write – Brian Ehlert

# Ask the path of the VHD and test it
Do {
    $imagePath = Read-Host "Please enter the full path to you VHD.  i.e. D:\VMs\MyTooBigVhd.vhd "
} until ((Test-Path -Path $imagePath ) -eq $true)  # Mount the VHD that will be getting resized

$orgVhd = Mount-DiskImage -ImagePath $imagePath -PassThru
$orgVhd = Get-DiskImage -ImagePath $orgVhd.ImagePath  # Get the partitions
$orgParts = Get-Partition -DiskNumber $orgVhd.Number  # Use DISM command line to capture the VHD one WIM file. Each partition with a different name.
$wimName = ($orgvhd.ImagePath.Split(".")[0] + ".wim") 
foreach ($part in $orgParts) {
    if ($part.Size -gt 524288000){ # skip the partition if it is less than 500MB, most likely there is no OS or it is the System Reserved partition.
        $capDir = $part.DriveLetter + ":\"
        $partNum = $part.PartitionNumber
        "Be patient, this could take a long time"
        & dism /capture-image /ImageFile:$wimName /CaptureDir:$capDir /Name:$partNum
    }
}
# dismount the VHD that was just captured
Dismount-DiskImage -ImagePath $orgvhd.ImagePath
# Get the size of the WIM. As the new VHD must be larger.
$wimFile = Get-ItemProperty $wimName
# Ask the size of the new VHD in GB
Do {
$newSize = [uint32](Read-Host "How large would you like the new VHD (in whole GB)?  The WIM is" ([uint32]($wimFile.Length /1024 /1024 /1024))"GB of data ")
} until ($newSize -gt ([uint32]($wimFile.Length /1024 /1024 /1024)))
$newSize = [uint64]$newSize * 1024  # convert GB to MB 
foreach ($part in $orgParts)
    {
    if ($part.Size -gt 524288000){ # skip the partition if it is less than 500MB.
        $capDir = $part.DriveLetter + ":\"
        $partNum = $part.PartitionNumber
        $newVhdPath = $orgvhd.ImagePath.Split(".")[0] + $partNum +"New." + $orgvhd.ImagePath.Split(".")[1]         
        $diskPart = @"
        create vdisk file="$newVhdPath" type=expandable maximum=$newSize
        select vdisk file="$newVhdPath"
        attach vdisk
        create partition primary
        active
        format fs=ntfs quick
        assign
"@
        $diskPart | diskpart
        $newVhd = Get-DiskImage -ImagePath $newvhdPath
        $newVhdDrive = (Get-Partition -DiskNumber $newVhd.Number)
        $newVhdLetter = (Get-Partition -DiskNumber $newVhd.Number).DriveLetter + ":"         
       
        "Be patient, this could take a long time"
       
        & dism /apply-image /ImageFile:$wimName /ApplyDir:$newVhdLetter /Name:$partNum
       
        New-PSDrive -PSProvider FileSystem -Name $newVhdDrive.DriveLetter -root ($newVhdDrive.DriveLetter + ":\") # Make the new volume known to your PowerShell session
       
        # if \Windows then assume a boot volume and create the BCD
        if ((Test-Path -Path ($newVhdLetter + "\Windows") -PathType Container) -eq $true)
        {
            bcdboot $newVhdLetter\Windows /s $newVhdLetter
        }
        Remove-PSDrive -PSProvider FileSystem -Name $newVhdDrive.DriveLetter
       
        Start-Sleep 10  # Settling time
        Dismount-DiskImage -ImagePath $newVhdPath
    }
}
 


Saturday, June 5, 2010

Importing the XenApp EVA is really this easy.

I’m going to import the XenApp 6 Evaluation Virtual Appliance into Citrix XenServer 5.6 using a new feature of XenServer 5.6 and XenCenter 5.6 called the Disk Image Import Wizard.

You can also watch this in action here: http://www.citrix.com/tv/#videos/2368

I will assume that you have already downloaded and installed XenServer 5.6 and XenCenter 5.6.

First, go to the download website for the Citrix XenApp EVA. http://www.Citrix.com/tryxenapp

A login with a MyCitrix user account is required. Be sure to download two items: the Getting Started Guide and the Evaluation Virtual Appliance package for XenApp 6.

After downloading the Evaluation Virtual Appliance, execute the CitrixXA6EVA.exe to expand the self extracting archive into a folder that contains a VHD and licensing documents.

Now, open (and read) the getting started guide. The import wizard requires some important information regarding the configuration of the virtual machine. On page four, the guide states that the EVA requires at least 2GB of RAM and the VHD requires at least 30GB of storage space. So make sure that your XenServer has a Storage Repository with at least 30GB of available space.

clip_image002

Open XenCenter and connect to a XenServer 5.6 host (using version 5.6 is required). In the left hand tree view select the host and then right click for the context menu and choose the Disk Image Import.

clip_image004

In the import wizard browse to and select the VHD and choose next.

Enter the information for the virtual machine. The VM needs a name, the number of virtual processors to assign and an amount of memory.

Note: I am unselecting the Run Operating System Fixups option because I know that this VM contains Server 2008 R2 and that it was built for Hyper-V. Server 2008 R2 can handle hardware changes pretty well (single to multiple processors, critical boot devices, etc.). XenServer also presents a critical boot device controller similar to the Hyper-V IDE specific boot device.

clip_image006

Then begin the import.

Once the import completes, select done.

At this time: power on the virtual machine and login at the logon screen. The domain and user account and password are in the Getting Started Guide.

If the screen of the VM flickers, Windows Server 2008 R2 is busy setting up some of the new hardware devices that it is detecting. You should still be able to login and complete the setup of the Evaluation Virtual Appliance environment.

If you would like to optimize the virtual machine for XenServer, install the XenServer tools within the virtual machine.

There is no “smoke and mirrors” involved here, it is literally this easy using the Disk Image Import wizard.

Wednesday, June 17, 2009

XenConvert 2.0.1 is released with VMware OVF compatibility

We have been working on adding Citrix Project Kensho OVF capabilities to XenConvert.

XenConvert is the free Citrix machine conversion utility.  It is primarily focused on converting workloads to either Provisioning Server or to XenServer, however there are some more generic functions that are of interest to most any virtualization folk.

The download can be found here:

http://www.citrix.com/English/ss/downloads/details.asp?downloadId=1855017&productId=683148

If this moves in the future go here: http://www.citrix.com/English/ss/downloads/results.asp?productID=683148 and look for XenConvert in the XenServer download section.

OVF packages from any existing VMware product (known to this date) can be consumed (imported) direct to XenServer.

The physical to OVF path can be run within a Windows machine and convert it to an OVF (meta file + .vhd) or just a vhd.

The OVF can then be consumed to XenServer with XenConvert 2 or to XenServer and / or Hyper-V in the upcoming Kensho refresh.

The VHD can, of course, be copied to any engine that uses vhd.

It also does a binary conversion of vmdk to vhd and injects a critical boot device driver that is compatible with XenServer (and works with Hyper-V).

Also, the XenServer .xva (vm backup files) can be converted to OVF.

Download and enjoy!

Thursday, April 9, 2009

Never resize a VHD with snapshots or differencing disks – more about differencing disks

I keep seeing this item coming up in the forums over and over again.

For some reason I need to make the virtual disk of my VM larger (maybe I downloaded too many patches, maybe too many temp files, maybe too many log files).

The reason does not really matter.

So I open the Edit Disk wizard, I find the VHD and I Expand the virtual disk.

Excellent, now my VM has more space and I go into the operating system and diskpart and perform the actions that I need to for the OS to use the additional space.

This works all to well when all you have is a single VHD.  One VHD, no snapshots, no differencing disks.

I have written about snapshots quite a bit over the past year.

A snapshot is a moment in time.  The technology that Hyper-V uses to achieve this is a Differencing Disk.

The differencing disk is a child disk that is linked to its parent.  The easiest way to describe the concept of the differencing disk is to think of overlays.

In the era of the small hard disk we used to think about sectors and blocks.  But things have changed, and most folks don’t concern themselves with that anymore – a disk is a place for stuff and that place has a capacity and that is all we really concern ourselves with.  It is the blocks and sectors that form the map that we need to be aware of.  Think of it like a dart board, but wil ar more rings.

The root VHD is the map of a disk.  A digital representation of a physical hard disk.  It has blocks, sectors, etc.

The differencing disk is also a map just like its parent, however, it only contains the blocks and sectors of its parent that are different, than the parent.

To begin my analogy, I am going to think of the single VHD as a map or drawing.

DiskMapRoot

Adding a differencing disk (taking a snapshot) is like laying a piece of tracing paper over a drawing, and only coloring in some features (the changes from the point the snapshot was made). 

DiskMapChild1

The drawing does not change, only the way the empty places are colored in.

If you add a second differencing disk (now a chain of three virtual disks – a grandparent VHD, a parent differencing disk – a child differencing disk).  This lays a second piece of tracing paper over the drawing, and we proceed to change how the empty spaces are colored in.

DiskMapChild2

What happens when you resize the VHD?

When you resize the VHD, the disk map or drawing, is changed.  I have a different combination of sectors and blocks.

DiskMapResize

Now, the spaces that I colored in on my tracing paper (differencing disks) no longer aligns with the empty spaces in the drawing.  The result is a really ugly picture.

DiskMapResizeOverlay

The result with my VM is that I just broke the chain.  And I broke it right at the root.

There is currently no method (that I know of) that will allow resizing of a virtual disk that contains snapshots – differencing disks.

If you need to resize the virtual disk of a VM and there are snapshots then the snapshots must be deleted (and the VM turned off, then wait patiently).  This has the end effect of taking each piece of tracing paper and applying its colors onto the layer underneath.   The term is called merging.

The layers of tracing paper are applied back to the primary drawing, the root VHD.

In the end, you have a single VHD that you can safely resize.

Is this the only way you can end up with a single VHD?  No I can think of at least a couple more creative ways to end up with a single VHD for resizing.

The key is that you cannot resize a virtual disk with snapshots or differencing disks.

I hope that someone that is thinking about doing this finds this article in Google or Live Search and saves themselves some big recovery pain.

Wednesday, December 17, 2008

You want to convert a machine to a vhd

So, for some reason you want to convert a machine to a vhd. Let me not limit your thinking by saying that this has to be a physcial machine, it could be a VM.

I am going to cover two items: XenConvert (free, converts running machine), and a Hyper-V feature (part of Hyper-V, converts any mountable disk).


Using Hyper-V:

With Hyper-V you can take a physical disk, attache it to a Hyper-V host and convert the disk (fully intact) to a VHD. A neat feature that no-one talks about.

This is great for a number of scenarios where you have a physical drive, a host, and the machine on the physical drive can be is is offline (we will assume that this is a disaster recovery exercise).

But those are the limitations. Still, a neat feature.

Here's how:
Mount the disk to a Hyper-V host. (SCSI, in an external enclosure, ATA, however)
Be sure that the disk is attached and recognized in Disk manager
Open Hyper-V manager
Select Actions -> New -> Hard Disk..
Step through the wizard to select your type of virtual disk, the location, then stop.
On the Configure Disk page, select the option "Copy the contents of the specific physical disk"
Then complete the wizard.

This then copies the contents of the desired physical disk (not just the files, but the actual blocks, formatting and all) to a VHD.

That is it.

Another option is to

Use XenConvert:
Download the XenConvert tool (You can download it from MyCitrix (@ Citrix.com) where you download XenServer)
Install it within the Operating System that you want to convert (again, physical or VM).
Then begin the conversion process choosing VHD as your output.
You can just convert an existing installation to VHD (it can even route the VHD to a network share using a mapped drive).

the benefit of XenConvert: You machine is running the entire time.
I have converted SQL, Operations Manager, and SCVMM servers to VHDs (yes, they boot and everything) then moved them to either Hyper-V or XenServer.

I hope you get creative with your options.
You can convert physical to virtual, virtual to virtual, etc. No need for expensive conversion tools as long as you have the time and the knowledge.

Tuesday, December 16, 2008

Should I put all my VHDs on one volume?

I recently responded to someone who was considering placing all of their VHDs onto one huge storage volume.

This might be easy for storage management and for backup management. But you have to consider the ancillary impacts that this might have on the overall environment.
The greatest impact will be the impact that each VM has upon another VM.

This is where we need to h ave a full understanding of all of the components involved in our virtualization infrastructure and how all of those components interact and affect each other.

Here is the statement that began the idea for putting this to blog:

"We were hoping to create a "big" LUN, store all our Hyper-V Guests on that LUN, assign the LUN to several HOSTS, and access the Guests that way."

Now, the response:

That is all fine, good, and noble - but you may want to reconsider.

Even VMware has had the recommendation (for a great number of years now) of no more than 10 VMs per LUN (they consider this a 'rule of thumb' that is taught in class).

Why? Disk IO.

You have to balance the disk IO demands of the VMs stored on the LUNs.

If you have VMs with a bunch of disk IO all happening at the same time they end up impacting each other.

For example - you always split out your SQL databases from the temp log, from the OS - for the same reason.

In this case you have different considerations - VM1 will impact VM2.

An easy test you can do at home:

With many VMs on a single LUN, boot one and wait for Integration Services to report some data from within the VM (Integration Services loads late in the stack so it is a good measure that the VM is nearly done booting).

Be sure to time it.

Now, repeat the test, this time with 4 VMs all at once.

Don't stop timing until all four are up, then get your average time to boot.

All that disk reading and page file building created massive disk IO.

Just something to think about as you plan your infrastructure.