A virtual machine is an abstract computer. It mimics a physical computer for the purpose of extending the flexibility of the computer system while still providing as many features of the physical environment as possible. Hyper-V, like most hypervisors, defines this abstract computer using files. The entities that abstract a physical computer’s hard drive(s) are, therefore, mere files. Specifically for Hyper-V, these files are in the VHDX format.
What is a VHD/X file?
VHDX is an semi-open file format that describes a virtual hard disk. The x was added to the current specification’s name so that it would not be confused with the earlier VHD format. Microsoft publishes this specification freely so that others can write their own applications that manipulate VHD/VHDX files, but Microsoft maintains sole responsibility for control of the format.
A VHDX mimics a hard disk. It is not related to formats, such as NTFS or FAT or EXT3. It is also not concerned with partitions. VHDX presents the same characteristics as a physical hard drive, or SSD, or SAN LUN, or any other block storage. It is up to some other component, such as the guest operating system, to define how the blocks are used. Simply, a VHDX that contains a possible NTFS format looks like the following:
Where can VHDX Be Used?
This is a Hyper-V blog, so naturally, I will usually only bring up VHDX in that context. It is not particular to Hyper-V at all. Windows 7 and Windows Server 2008 R2 were able to directly open and manipulate VHD files. Windows 8+ and Windows Server 2012+ can natively open and manipulate VHDX files. For instance, the Disk Management tool in Windows 10 allows you to create and attach VHD and VHDX files:
When mounted, the VHDX then looks to the operating system like any other disk:
The most important thing to know is that whether or not you can use VHDX depends entirely upon the operating system that controls the file, not anything inside the data region of the file. The contents of the data area are an issue for the operating system that will control the file system. If it’s used by Hyper-V, then that is the guest operating system. If the VHDX is mounted in Windows 10, then Windows 10 will deal with it entirely. It will do so using two different mechanisms.
The VHDX Driver
Modern Windows operating systems, desktop, server, and Hyper-V, all include a driver for working with VHDX files. This is what that driver sees when it looks at a VHDX:
Windows 7 and Windows/Hyper-V Server 2008 R2 and earlier cannot mount a VHDX because they do not contain a VHDX driver. They can only work with the earlier VHD format. If a VHDX driver existed for those operating systems, they would theoretically be able to work with those file types. Logically, this is no different than attaching a disk via a SCSI card that the operating system may or may not recognize.
The File System Driver
The file system driver sees only this part:
There is no indication that the visible contents are held within a VHDX. They could just as easily be on a SAN LUN or a local SSD. For this reason, it does not matter at all to any guest operating system if you use VHDX or some other format. Linux guests can run perfectly well from their common ext3 and ext4 formats when inside a VHDX.
When a VHDX is mounted in Windows 10 or a server OS, it will require both the VHDX driver and the file system driver in order to be able to manipulate and read the contents of the file. You can mount a VHDX containing ext3 partitions inside Windows 10, but it will be unable to manipulate the contents because it doesn’t know what to do with ext3.
Should I Use VHD or VHDX?
If you will never use the virtual disk file with down-level management operating systems (Windows 7 or Windows/Hyper-V Server 2008 R2 or earlier), then you should always use VHDX (remember that guest operating systems don’t know or care which you use). Unless things have changed, Azure still can’t use a VHDX either, but you can replicate your VHDXs there. If you need to mount them on the Azure side, they will be automatically converted to VHD, although you do need to stay below the 1TB maximum size limit for Azure. If anyone has updated information that the Azure situation has changed, please let me know.
Configuration Information for VHDX Files
There are a few things to understand about VHDX files before creating them. I have explained the process for VHDX creation in another article.
Generation 1 (VHD) vs. Generation 2 (VHDX)
I’ve seen some people use the Generation 1 and Generation 2 labels with VHD and VHDX. They’re correct in the abstract sense, but the capitalization is wrong because these are not formal labels. I encourage you not to use these terms at all, because they easily become confused with Generation 1 and Generation 2 Hyper-V virtual machines. A Generation 1 virtual machine can use both VHD and VHDX as long as the management operating system can use both. A Generation 2 virtual machine can only utilize VHDX.
VHDX Block Sizes
The block size for a VHDX has nothing to do with anything that you know about block sizes for disks in any other context. For VHDX, block size is the increment by which a dynamically-expanding disk will grow when it needs to expand to hold more data. It can only be set at creation time, and only when you use PowerShell or native WMI commands to build the VHDX. For a fixed disk, it is always 0:
The default block size is 32 megabytes. This means that if a VHDX does not have enough space to satisfy the latest write request and has not yet reached the maximum configured size, the VHDX driver will allocate an additional 32 megabytes for the VHDX and will perform the write. If that is insufficient, it will continue allocating space in 32 megabyte blocks until the write is fully successful. While this article is not dedicated to dynamically expanding VHDXs, I want to point out that there is persistent FUD that these expansion events kill performance.
The people making that claim have absolutely no idea what they’re talking about. A heavily-written VHDX will either reach its maximum size very quickly and stop expanding or it will re-use blocks that it has already allocated. A VHDX simply cannot spend a significant portion of its lifetime in expansion, therefore it is impossible for expansion to cause a significant performance impact.
Expansion events will cause the new data blocks to be physically placed in the next available storage block on the management operating system’s file space. This, of course, will likely lead to the VHDX file becoming fragmented. Disk fragmentation in the modern datacenter is mostly a bogeyman used to terrify new administrators and sell unnecessary software or oversell hardware to uneducated decision makers, so expect to be confronted with a great deal of FUD about it. Just remember that disk access is always scattered when multiple virtual machines share a storage subsystem and that your first, best way to reduce storage performance bottlenecks is with more array spindles/SSDs.
For Linux systems, there is a soft recommendation to use a 1 megabyte block size. Space is allocated differently with the Linux file systems than NTFS/ReFS. With the 32 megabyte default, you will find much more slack space inside a Linux-containing VHDX than you will inside a Windows-containing VHDX. The recommendation to use the smaller block size can be considered soft because it doesn’t really hurt anything to leave things be — your space utilization just won’t be as efficient.
VHDX Sector Sizes
The term sector is somewhat outdated because it refers to a method of mapping physical drives that no one uses anymore. In more current terms, it signifies the minimum amount of space that can be used to store data on a disk. So, if you want to write a bit of data to the disk that is smaller than the sector size, it will pad the rest of the space with zeroes. The logical sector size is the smallest amount of data that the operating system will work with. The physical sector size is the smallest amount of data that the physical device will use. They don’t necessarily need to be the same size.
If the logical sector size is smaller than the physical sector size, read and write operations will be larger on the actual hard drive system. The operating system will discard the excess from read operations. On write operations, the physical drive will only make changes to the data indicated by the operating system although it may need to touch more data space than was called for. There are a great many discussions over “performance” and “best” and the like but they are all largely a waste of time. The VHDX driver is an intermediate layer responsible for translating all requests as best it can. The true performance points are all in the physical disk subsystem. To make your I/Os the fastest, use faster hardware. Do not waste time trying to tinker with VHDX sector sizes.
Remember that “portability” is a major component of virtualization. If you do spend a great deal of time ensuring that your VHDX files’ sector sizes are perfectly in-line with your physical subsystem, you may find that your next storage migration places your VHDXs in a sub-optimal configuration. The “best” thing to do is use the defaults for sector sizes and let the VHDX driver take care of it.
VHDX Files Do Not Permanently Belong to a Virtual Machine
When you create a virtual machine using any of the available GUI methods, you’re also given the opportunity to create a VHDX. Behind the scenes, the virtual machine creation and the virtual hard disk creation are two separate steps, with the act of attaching the VHDX to the virtual machine being its own third operation. That final operation will set the permissions on the VHDX file so that the virtual machine can access it, but it does not mean that the VHDX requires the virtual machine in order to operate. A virtual hard disk file:
- Can be detached from one virtual machine and attached to another
- Can be re-assigned from one controller and/or controller location to another within the same virtual machine
- Can be mounted in a management operating system
I have an article explaining the process for VHDX attachment; it shows the various elements for controller selection as well as remove options so that you can perform all of the above. As for the VHDX files themselves, they can be transported via copy, xcopy, robocopy, Windows Explorer, and other file manipulation tools. If a virtual machine somehow loses the ability to open its own VHDX file(s), use this process to detach and reattach the VHDX to the virtual machine; that will fix any security problems.
Mount a VHDX File to Read in Windows (Even Your Desktop!)
As briefly mentioned in the opening portion of this article, you can mount a VHDX file in Windows 10 (as well as Windows 8 and 8.1 and Windows Server 2012+). This allows you to salvage data from a VHDX file if its original operating system had some sort of fatal problem. You can use it for more benign situations, such as injecting installation files into a base image. Just right-click on the file in Windows Explorer and click Mount:
All of the partitions will then be assigned drive letters in your management operating system and you can work with them as you would any other partition.
Note: When mounting VHDX files that contain boot partitions, you will sometimes get Access Denied messages because the file system drivers can’t read from those partitions. These messages do not impact the mount action.
When you’re done, just right-click on any of the partitions and click Eject. If there are no partitions visible in Windows Explorer, right-click the disk in Disk Management and click Detach VHD.
Mount a VHDX File Using PowerShell
You can use PowerShell to mount a VHDX only on systems that have Hyper-V installed. Just having the Hyper-V PowerShell module installed is not enough.
Mount a VHDX:
Mount-VHD -Path D:ImportsImportedDisk.vhdx
Dismount a VHDX:
Dismount-VHD -Path D:DemoDemoDisk.vhdx
If you know the disk number of the mounted VHDX, you can use the -DiskNumber parameter instead of the -Path parameter.
Copy a Physical Disk to a VHDX
There are many ways to get a physical disk into a VHDX. Be aware that just because you can convert a disk to VHDX does not mean that it can successfully boot inside a virtual machine! However, it will always be readable by any management operating system that can mount a VHDX and has the proper file system driver. These are the most common ways to convert a physical drive to VHDX:
- Directly attach a physical drive to the system, then use the VHD creation wizard to copy its contents to a VHDX (see step 6).
- Use Disk2VHD.
- Use the Microsoft Virtual Machine Converter. MSVMC can currently generate a virtual machine from another virtual machine or perform a physical-to-virtual conversion (P2V) of a physical computer.
Backup and Restore VHDX Files
The “best” way to do backup and restore of a virtual machine is to use a backup application specifically built for that purpose. But, the poor man’s way involves just copying the VHDX files wherever they are needed. For a “restore”, you’ll need to attach the virtual disks to the virtual machine that will own them.
Attach an Existing VHDX to an Existing Virtual Machine or Reset VHDX File Security
Occasionally, you’ll need to (re)connect an existing VHDX file to an existing virtual machine. Sometimes, you have to rebuild the virtual machine because its XML file was damaged. I sometimes do this because I have VHDX files that I use for templates that I can usually patch offline, but sometimes need to bring online.
While not directly related to the preceding, there are times when a virtual machine loses the ability to open a VHDX. This is invariably the rest of an administrator or security application removing necessary permissions from the VHDX file, often by erroneously setting inheritance from its containing folder.
Both problems have the same solution: use the attach directions. Hyper-V will automatically set the permissions as necessary when it connects the VHDX to the virtual machine.
Move a VHDX from One Bus to Another on the Same Virtual Machine
Generation 1 virtual machines have both a virtual IDE bus and a virtual SCSI bus. It’s rare, but sometimes you’ll want to move a VHDX from one to the other. The volume that contains the system bootstrapper must always be IDE 0 disk 0 (the first one), but any other disk can be moved.
You might need to do this because you accidentally placed a Windows page file on a virtual SCSI disk, which usually doesn’t work (and wouldn’t help with performance if it did, so stop that) or because you discovered the hard way that online resize operations don’t work with IDE-connected VHDX files. You can, of course, also move between different controllers and positions on the same bus type, if you have some need to do that.
Remember that you cannot modify anything on a VHDX connected to the virtual IDE bus while the virtual machine is online. The virtual SCSI bus allows for online modification.
Use the GUI to Move a VHDX to another Bus or Location
You must use Hyper-V Manager for non-clustered virtual machines and Failover Cluster Manager for clustered virtual machines. Or you could use some other application not covered here, like SCVMM.
In the relevant tool, open the settings dialog for the virtual machine and click the drive that you want to change. On the right, choose the new destination bus and location:
Notice that as you change the controller, the dialog contents will change automatically so that it already appears to be on the destination location before you even click OK or Apply. It will also show In Use for any location that already has an attached drive.
Use PowerShell to Move a VHDX to another Bus or Location
In PowerShell, use Set-VMHardDiskDrive to relocate a VHDX:
Set-VMHardDiskDrive -VMName svtest -ControllerType IDE -ControllerNumber 1 -ControllerLocation 1 -ToControllerType SCSI -ToControllerNumber 0 -ToControllerLocation 0
Warning: If running through a remote PowerShell session, be extremely mindful about second hop and delegation concerns. While it is not obvious, the above cmdlet first detaches the drive from its current location and then attaches it at the specified destination. Far fewer permissions are required to detach than attach. It is entirely possible that you will successfully detach the VHDX… and then the cmdlet will error, leaving the disk detached.