Script To Convert Hyper-V Virtual Machine From VHD To VHDX

Last year I wrote a script that would allow you to specify a virtual machine, and the script would:

  1. Shut down the VM if running
  2. Seek out any VHD files attached to any of the VM’s controllers
  3. Create VHDX files from those VHD files
  4. Replace the VHD files by attaching the VHDX files to the same controllers and locations in the VM settings
  5. Delete the VHD files

In my tests, the script had some issues. But that was nearly a year ago and it was on WS2012 in my lab. The script remained untouched until yesterday. I was chatting with my fellow Hyper-V MVP, Didier Van Hoye (aka @workinghardinit). He told me he was in the process of migrating VMs from an old W2008 R2 cluster to WS2012 and was going to be converting VHD files. Aha! This might be a time for a solution to speed up the process.

I sent the script over to Didier to have a look-see. Would it work. Well, Didier ran a series of tests this morning with guest OSs including W2003 R2 and WS2012. The tests ran flawlessly.

So … here is the script. FYI there are few things to note:

  • You might consider putting in a delay loop to test if the VM is actually shut down if you need to shut it down. Put a timeout of 3 minutes in that. The stop-vm cmdlet is async so it shouldn’t cause an issue as it is below, but you might want to take the extra step, just in case.
  • You might want to comment out the line Remove-VMHardDiskDrive $VHD for your test or pilot runs.
  • I do not support this script 🙂
  • Run the script and specify the VM name as a parameter.

CREDIT: A big thank you to Didier Van Hoye (aka @workinghardinit) for checking my work.

#—-

[CmdletBinding ()]
Param   (
        [Parameter(Mandatory=$True)]
        [string]$VMName
        )

#Disable error reporting – comment out the following line if you need to troubleshoot the script
$ErrorActionPreference = "SilentlyContinue"

cls

$VM = Get-VM $VMName
$VMStatus = $VM.State

if ($VM.VMid -ne $NULL)
{
    if ($VMStatus -eq "Running")
    {  
        #Shut down the VM if it is running
        Write-Host "Shutting down" $VMName
        Stop-VM $VMName  
    }

    #Get the disks in the VM
    $AllVHD = Get-VMHardDiskDrive $VMName

    if ($AllVHD -eq $NULL)
        {
        Write-Host "There are no virtual hard disks to convert"
        Exit
        }

    foreach ($VHD in $AllVHD)
    {
        #Get the VM path and create a VHDX file path
        [string]$VHDFile = Get-Item $VHD.Path
        $VHDFormat = (Get-VHD $VHDFile).VhdFormat
        if ($VHDFormat -eq "VHD")
            {
            [string]$VHDXFile = $VHDFile + "x"

            [string]$ControllerType = $VHD.ControllerType
            [string]$ControllerNumber = $VHD.ControllerNumber
            [string]$ControllerLocation = $VHD.ControllerLocation

            Write-Host "Converting: " $VHDFile "to" $VHDXFile
            Convert-VHD –Path $VHDFile –DestinationPath $VHDXFile
            Sleep 10

            #Reconfigure the Physical Sector Size of the VHDX file to 4 K
            Set-VHD -Path $VHDXFile -PhysicalSectorSizeBytes 4096
            Sleep 10

            #Remove the old VHD
            Write-Host "Removing $VHDFile from $VMName"
            Remove-VMHardDiskDrive $VHD
            Sleep 10
            #Replace the VHD with the VHDX
            Write-Host "Adding $VHDXFile to $VMName"
            Add-VMHardDiskDrive -VMName $VMName -Path $VHDXFile -ControllerType $ControllerType -ControllerNumber $ControllerNumber -ControllerLocation $ControllerLocation

            #Danger Will Robinson – we are going to delete the original VHD – we hope you have a tested VM backup!
            Write-Host "Deleting $VHDFile"
            Remove-Item $VHDFile -Force
            }
        else
            {
            Write-Host "$VHDFile is already a VHDX file: skipping"
            }
    }

    if ($VMStatus -eq "Running")
    {  
        #Restart the VM if it was running before the conversion
        Write-Host "Starting" $VMName
        Start-VM $VMName  
        #Wait for 10 seconds
        Write-Host "Waiting for 10 seconds to verify the virtual machine …"
        Sleep 10
        $VMStatus = $VM.State
        if ($VMStatus -ne "Running")
        {
            #Something went wrong
            Write-Host "$VMName could not reboot – please restore the VM from backup"     
        }
    }

}
else
{
    Write-Host $VMName "does not exist on this host"
    Exit
}

Write-Host "Processing of $VMName has completed"

KB2929766 – Configuring Paging File In Hyper-V VM’s SCSI Drive Fails

When enabling Hyper-V Replica for Windows VMs, it is recommended to move the guest OS paging file from the C: drive to another virtual hard disk. This allows you to deselect that paging file virtual hard disk from replication, thus saving needless bandwidth.

Microsoft has published a support article for when configuring a page file on a SCSI drive fails on Generation 1 Hyper-V virtual machine.

Symptoms

Consider the following scenario:

  • You create a virtual machine that is running on Windows Server 2008 R2 or Windows Server 2012 Hyper-V.
  • You manually configure a page file on a non-system drive, which is a virtual hard disk (VHD) attached to emulated SCSI adapter.
  • You restart the virtual machine.

In this scenario, no Pagefile.sys is created under the selected drive. Additionally, on Windows Server 2008 R2 Hyper-V, you receive the following error message

Windows created a temporary paging file on your computer because of a problem that occurred with your paging file configuration when you started your computer. The total paging file size for all disk drives may be somewhat larger than the size you specified.

Status

This behavior is by design.

In generation 1 virtual machines, you should create a virtual hard disk on the VM’s IDE controller and move the paging file to that new disk. There are no issues with the paging file being on a SCSI controller in generation 2 virtual machines; they don’t have IDE controllers.

KB2920193 – Virtual Hard Disk Can’t Be Created On WS2012 SMB Share Without Resiliency

Another hotfix, KB2920193, has been released by Microsoft, this time to deal with a scenario where a virtual hard disk cannot be created on an SMB server without resiliency support from a Windows 8 or Windows Server 2012 computer.

Assume that you have a computer that has Windows 8 or Windows Server 2012 installed and you are connected to a server share across a SMB2 link that does not support resiliency. Resiliency is an optional feature beginning with SMB 2.1 and some SMB2 implementations do not support resiliency. Then, you experience one of the following issues:

  • When you use Windows Server Backup, you receive the following error message: Backup failed to complete. There was a failure in preparing the backup image.
  • When you use Hyper-V manager to create a VHD or VHDX, you receive the following error message: The filename \<system><share>New Virtual Hard Disk.vhdx is reserved for use by Windows.
  • When you try to mount an .ISO image by right-clicking on the .ISO file in Explorer and select mount from the right-click menu, you receive the following error message: sorry there was a problem mounting the file.
  • When you use the Win32 API, CreateVirtualDisk() fails.

Uhhh, SMB 2? Huh? Just use WS2012 on all ends to stick with SMB 3.0 and avoid this issue.

A hotfix is available from Microsoft

KB2908243 – WS2012 Computer With NIC Teaming Loses Network Connectivity

Microsoft released KB2908243 to deal with a situation where a Windows Server 2012-based computer on which you configured NIC Teaming has no network connectivity.

Consider the following scenario:

  • You have a computer that is running Windows Server 2012.
  • You configure NIC Teaming, also known as load balancing and failover (LBFO), on the computer.
  • You restart the computer.

In this scenario, you may find that the computer has no network connectivity. However, when you restart the computer, network connectivity is restored.

A supported hotfix is available from Microsoft Support.

KB2919393 – Update Rollup For WS2012

Microsoft has released a February update rollup for Windows Server 2012, as well as Windows 8 and Windows RT (8). There’s one included update that Hyper-V or clustering folks should be aware of:

KB2920469 deals with a situation where you cannot change the schedule for CAU self-updating mode in Windows Server 2012 or Windows Server 2012 R2 by using CAU GUI.

Assume that you have a cluster that runs Windows Server 2012 or Windows Server 2012 R2. When you try to change the Cluster-Aware Updating (CAU) schedule by using the GUI, the time for the automatic update schedule is not changed, and the old time remains.

As usual with update rollups, don’t be an IT haemophiliac; delay approval of this update for a month and let the rest of the world be Microsoft’s test lab. If you don’t see any update to this update in one month, then approve and deploy it if you’re happy.

KB2928127 – Supported File Paths For Hyper-V Virtual Machine Storage

I am pretty particular about where I store virtual machine files. I STRONGLY DISLIKE the default storage paths of Hyper-V. I use 3 options:

  • Local storage: Virtual hard disks and virtual machine files go into D:Virtual Machines<VM Name>
  • CSV: Virtual hard disks and virtual machine files go into C:ClusterStorage<CSV Mount Name><VM Name>
  • SMB 3.0: Virtual hard disks and virtual machine files go into \<SMB 3.0 Server Name><Share Name><VM Name>

Each VM gets its own folder. All files for that VM, including virtual hard disks, go into that folder. I NEVER use the default VM file locations on the C: of the management OS. Using those locations is STUPID. And if you cannot see why … please put down the mouse and hand in your resignation now.

Microsoft has published a KB article to reinforce the fact that there are supported file share path formats. The wording is a bit iffy – see my above examples to see what is supported. Long story short: Place the VM files into a dedicated subfolder for that VM.

KB2846340 – Duplicate Friendly Names Of NICs Displayed In Windows

This KB applies to Windows Vista and Windows Server 2008 up to Windows 8 and Windows Server 2012. There’s no mention of Hyper-V, but considering that hosts have lots of NICs, it seemed relevant to me. The scenario is when duplicate friendly names of network adapters are displayed in Windows.

Symptoms

Consider the following scenario:

  • You have one or more network adapters installed on a computer that is running one of the following operating systems:
    • Windows Vista
    • Windows Server 2008
    • Windows 7
    • Windows Server 2008 R2
    • Windows 8
    • Windows Server 2012
  • The display names of the network adapters are changed. For example, the device driver is updated.
  • You add new network adapters to the computer. The new network adapters are of the same make and model as the original network adapters.

In this scenario, duplicate friendly names of the original network adapters are displayed in Device Manager.
For example, you have two network adapters installed on a computer. Before you update the driver, Device Manager shows the following:

  • <Network adapter name>
  • <Network adapter name> #2

After the driver is updated, the names of the network adapters are changed to the following in Device Manager:

  • <Network adapter new name>
  • <Network adapter new name> #2

After you add new network adapters that are of the same make and model, Device Manager shows the following:

  • <Network adapter new name>
  • <Network adapter new name> #2
  • <Network adapter new name> #3
  • <Network adapter new name> #4
  • <Network adapter new name> #5
  • <Network adapter new name> #6
  • <Network adapter new name>
  • <Network adapter new name> #2

In this scenario, Device Manager displays duplicate friendly names of the original network adapters.

A hotfix is available to resolve this issue.

KB2914974–Cluster Validation Wizard Might Not Discover All LUNs On WS2012 Or WS2012 R2 Failover Cluster

The Failover Cluster Validation Wizard can perform a number of storage tests to determine the suitability and supportability of the shared storage of a potential new cluster. This is important for a Hyper-V cluster that will use directly attached shared storage such as a SAN (not SMB 3.0).

Microsoft has published a KB article for when these storage tests on a multi-site (stretch, cross-campus, or metro) failover cluster may not discover all shared LUNs on Windows Server 2012 or Windows Server 2012 R2.

Symptoms

Consider the following scenario:

  • You have a Windows Server 2012 or Windows Server 2012 R2 multi-site failover cluster.
  • A multi-site storage area network (SAN) is configured to have site-to-site mirroring.
  • You use the Validate a Configuration Wizard to run a set of validation tests on the failover cluster.

In this scenario, storage tests may not detect all logical unit numbers (LUNs) as shared LUNs.

Cause

Storage validation test selects only shared LUNs. A LUN is determined to be shared if its disk signatures, device identification number (page 0×83), and storage array serial number are the same on all cluster nodes. When you have site-to-site mirroring configured, a LUN in one site (site A) has a mirrored LUN in another site (site B). These LUNs have the same disk signatures and device identification number (page 0×83), but the storage array serial number are different. Therefore, they are not recognized as shared LUNs.

Resolution

To resolve the issue, run all the cluster validation tests before you configure the site-to-site LUN mirroring.

Note If the validation test is needed afterward for support situations, LUNs that are not selected for storage validation tests are supported by Microsoft and the storage vendor as valid Shared LUNs.

KB2916993 – Stop Error 0x9E In WS2012 Or Windows 8

This KB article looks like it affects Windows Server 2012 clusters so I’m including it in today’s posts. The fix is for when a stop error 0x9E in Windows Server 2012 or Windows 8.

Symptoms

When you have a cluster node that is running Windows Server 2012, you may encounter a 0x9E Stop error.

Cause

This issue occurs because of lock contention between the memory manager and the Cluster service or a resource monitor when a large file is mapped into system cache.

A hotfix is available to resolve this issue.

KB2913695–OffloadWrite Does PrepareForCriticalIo For Whole VHD On WS2012 Or WS2012 R2 Hyper-V

Microsoft has published a hotfix for when OffloadWrite is doing PrepareForCriticalIo for the whole VHD in a Windows Server 2012 or Windows Server 2012 R2 Hyper-V.

Symptoms

Consider the following scenario:

  • You have a Hyper-V host that is running Windows Server 2012 or Windows Server 2012 R2.
  • You run a copy for a file in a virtual machine.
  • There is an offload write for Virtual Hard Disk (VHD) in the host.

In this scenario, NTFS in the host would do PrepareForCriticalIo for the whole VHD. This operation may cause the following bad consequences for Cluster Shared Volumes:

  • Redirected I/O may be time-out.
  • Snapshot creation can be stuck until the offloadWrite is complete.
  • Volume dismount will be blocked by inflight I/O. This can cause the Physical Disk Resource to be detected as deadlocked if dismount takes more than 3 minutes, or the cluster node to be bug checked if dismount takes more than 20 minutes.

A hotfix is available for this issue.