Importing Hyper-V VM from a PowerShell Backup

My Petri article this week is on importing Hyper-V VMs from a backup. http://bit.ly/PRE0pk I have many more articles on Hyper-V on Windows 8 on the site as well. You can find all of my recent posts here.

PowerShell Hyper-V Memory Report

Since moving to Windows 8, I’ve continued exploring all the possibilities around Hyper-V on the client, especially using PowerShell. Because I’m trying to run as many virtual machines on my laptop as I can, memory considerations are paramount as I only have 8GB to work with. Actually less since I still have to run Windows 8!

Anyway, I need to be able to see how much memory my virtual machines are using. The Get-VM cmdlet can show me some of the data.

Actually, there are more properties I can get as well.

Those values are in bytes so I would need to reformat them to get them into something more meaningful like bytes. Not especially difficult, but not something I want to have to type all the time. Now, I can also get memory information with Get-VMMemory and this is formatted a little nicer.

What I like about this cmdlet is that it also shows the buffer and priority settings.

In the end, I decided the best course of action was to build my own function that combined information from both cmdlets. The result is a custom object that gives me a good picture of memory configuration and current use. The function, Get-VMMemoryReport, is part of a larger HyperV toolkit module I’m developing but I thought I’d share this with you now.

I wrote the function with the assumption of piping Hyper-V virtual machines to it. Although I can also pipe names to it and the function will then get the virtual machine.

Once the function has the virtual machine object, it also gets data from Get-VMMemory.

Finally, it creates a hash table using the new [ordered] attribute so that the key names will be displayed in the order I enter them. I use this hash table to write a custom object to the pipeline. I could have used the new [pscustomobject] attribute as well, but I felt in a script using New-Object was a bit more meaningful. With this command, I get output like this:

Or I can explore the data in other ways. I can create an HTML report, export to a CSV or take advantage of Out-GridView.

Here’s the report for my currently running virtual machines.

The function defaults to connecting to the localhost, but I am assuming that if you have an Hyper-V server you could use this from any system that has they Hyper-V module also installed. I don’t have a dedicated Hyper-V server to test with so maybe someone will confirm this for me.

In the meantime, download Get-VMMemoryReport and let me know what you think.

Hyper-V VHD Summary

When I made the move to Windows 8, one of my tasks was to migrate my test environment from VirtualBox to Hyper-V. Windows 8 includes a client Hyper-V feature that is easy to use and includes PowerShell support. Plus I needed to expand my Hyper-V skills anyway, especially from the console. After setting up a number of VMs, I realized I needed to get a handle on disks: what files were in use for which VM? The Get-VM cmdlet writes a VirtualMachine object to the pipeline. One of its properties is HardDrives.

The property is actually a nested object.

That tells me where the VHD is, but not about it. For that I can use Get-VHD.

There is some great information here like sizes, type and format. All I need now is a way to combine all of this information so that for every VM I can get a summary of pertinent VHD information. This is a great scenario for using Select-Object and creating a custom property.

In the hash table, the Expression script block is running Get-VHD and returning the Size property. Eventually I want this for all VMs which means I’ll need to expand the HardDrives property.

That is very promising. In fact, let’s cut to the chase.

This function writes a summary object for each VM which means I can further sort, filter or whatever I need to do. Because this can take a bit of time to run, I’ll save the results to a variable.

One unexpected bonus was that it helped me identify a VM with a “bad” VHD reference.

This was a file I had renamed, which “broke” the virtual machine. Or I can see how much space my VHD files are taking.

Or perhaps I need to back them all up.

Awesome. But…..my function is based on code I developed to run from the command line which works great as a one line command. I’m not likely to have a great number of virtual machines so performance isn’t that big a deal. Plus I could always run it as a job. If I’m going to turn this into a function, perhaps it makes sense to break this up.

If you look at my function, I’m running Get-VHD multiple times for the same file. It probably makes more sense to only get it once. Here’s a revised block of code.

I’ll get the same result, and actually faster. My first version took 7.8 seconds and this takes 2.3 seconds. Because this is a function, I only have to type it once so I can add comments and even a progress message with Write-Host. This isn’t too say I can’t do this all from the console; it is just a bit more tedious.

The purpose of my post is to not only demonstrate some of the Hyper-V cmdlets, but also that what you type at the console doesn’t always make the best PowerShell script. Sometimes you need to re-think things for performance and maintainability.

Download Get-VHDSummary.