We all like to think that when we built our Hyper-V server that we carefully mapped out storage requirements. But if you are an IT professional that has been around for any length of time you know that sometimes the best laid plans can quickly go out the window. In short, there may be any number of reasons why you might need to relocate storage associated with a Hyper-V virtual machine.

This might mean not only associated VHD or VHDX files but paging files and snapshots as well. If you only have a single virtual machine, I think it is just as easy to select the virtual machine in the Hyper-V manager and use the Move action which I’ve highlighted in Figure 1.

You can use the wizard to move files to new locations. But if you need to manage a migration for multiple machines, then PowerShell I think is the best choice. The latest version of Hyper-V includes a PowerShell cmdlet called Move-VMStorage. You can move VHD/VHDX files, snapshots and/or paging files. Here’s one of my virtual machines that has a single VHD file.

If I wanted to move all storage to a new folder, the necessary PowerShell command is pretty simple.

As you can see it also support –Whatif. Depending on the size of the file or files this command might take some time to run so you have the option of running it as a PowerShell background job.

When finished there will be subfolders under E:\VMStorage for the hard disk, snapshot and configuration files. It is also possible to move individual components.

With this command I moved the snapshots from the virtual machine to a new location. I didn’t even have to create the Snapshots folder ahead of time. PowerShell did it for me. Think about this for a moment. If I can do this for a single virtual machine I can do it for 10 or 100. Let’s say I want to move snapshots for all of my Chicago virtual machines to this location. It is a one line command.

Once I’ve verified this is what I want I can run this as a PowerShell background job.

Each movement will be a separate job. There is one caveat, however. This command will be dependent on the server configuration for simultaneous storage migrations. When you run this command as a background job, each migration happens simultaneously which can lead to failures. You can either run the command without using –AsJob you’ll need to add some logic to your command or throttle your jobs accordingly. Or don’t use the –AsJob parameter at all!

Lastly, you can also elect to move virtual disk files, although this is a bit more cumbersome. The –VHDS path expects a specially constructed hash table using the format @{“SourceFilePath”=<source vhd file path>;”DestinationFilePath”=<destination vhd file path>}. The file path must include the file name and it must be the same in both the source and destination. Here’s an example that moves the VHD file from F:\VHD to E:\VMStorage.

This presumes you know in advance the path and name of the VHD or VHDX file. It is possible with a little work to build this with some PowerShell code.

If the virtual machine had multiple hard drives they would all go to the same, new location in separate Move-VMStorage commands. It is possible to build an array of hash tables for all the drives and pass that as a value to –VHDS in a single Move-VMStorage command, but my approach works just fine since as far as I can tell only one file is copied at a time anyway.

Everything I’ve shown you can be mixed into the same expression. This means you could move snapshots to one location, hard drives to another and paging files to yet another. And to top it off, you can migrate while the virtual machine is running! Although, personally I would avoid migrations during periods of heavy use to avoid any unexpected problems.

Before you start migrating storage around you network, take some time to read the help and examples for Move-VMStorage and test your commands with non-production virtual machines. If you’d like to see more Hyper-V and PowerShell content, please let me know.