Summary: Use Windows PowerShell to find your virtual machines in a recovered file system.
Hey, Scripting Guy! This week were working on some business continuity and disaster recovery practices. One of the documents we are building involves how to rebuild a Hyper-V machine in our Windows Server 2012 R2 environment. Can you tell me if there is a way to identify the configuration data for Hyper-V? Is it hard? Oh please tell me oh wise Scripting Guy!
Honorary Scripting Guy, Sean Kearney here—filling in for our good friend Ed. He’s taking the week off and playing with some cool scripts for fun. Yes, our good friend is as geeky as the rest of us.
So with Hyper-V in Windows Server 2008 through Windows Server 2012 R2, the configuration data has always been stored in an .xml file.
Oh good! Done. Hey, Scripting Guy! Blog post complete! We’ll run:
GET-CHILDITEM –recurse –include *.XML –force
And poke through the pile. WooHoo!
Yes. We could do that. But that would be pretty pointless, wouldn’t it? XML is not only used by Hyper-V, it’s used by Visual Studio, Internet data, and so many applications that you could spend an entire weekend just reading .xml files for Hyper-V data.
That’s absolutely fine if you enjoy doing that—everybody has to have a hobby.
I particularly enjoy finding a way for the computer to do the work for me. So let’s take a look at a sample .xml file for Hyper-V. I have one handy here under my C:\VM folder where I store my machines on my laptop for demos.
To pull it’s configuration so we can look at it, we need to run Get-Content against the item and store in a strong type [XML] variable:
[XML]$HyperVConfig=GET-CONTENT C:\VM\TestDC\TestDC\Virtual Machines\C32AFB36-F9BB-4001-98C1-D2CBE8AD26CD.xml
After it is stored, we can examine the properties that are unique to a Hyper-V virtual machine. The one we’re going to be concerned with is the DisplayName of the virtual machine. It’s stored in the XML tree under Configuration.Properties.Name:
By looking at this file, we see there is a property call #text, which contains the name of our virtual machine. Even though its file name is written in some type of Klingon (sorry, that’s what a GUID looks like to me), we can identify the virtual machine for this configuration.
But if we try to access this property by its name, the console will prompt us for more information, as you see here:
That’s because the “#” is special to the Windows PowerShell interpreter. So we need to tell the console, “Hey! All of this belongs to me. Don’t you dare try to interpret it!” We can do this simply enough by enclosing it within quotes like this:
Pretty cool, eh?
The other piece we’ll watch for are properties that are unique to virtual machines, such as the “Last Powered-On Time.” There are other .xml files owned by Hyper-V that have the #text information as a description, but not as a virtual machine. Resources are one example. So well trap for a piece of information that is unique to a virtual machine.
Armed with this information, we can build a pretty simple and cool script that will do three things:
- Identify the .xml files that are virtual machine configurations for Hyper-V
- Display the name
- Store it in a .csv file
For this script, I’m going to target the C:\ProgramData folder, which is the default location that the XML data is stored in. But you could also target the root of a folder structure if you have no idea where the data is stored.
First get all potential .xml files:
$HyperVList=GET-CHILDITEM C:\ProgramData –recurse –include *.XML –erroraction ‘SilentlyContinue’
Next we get the content of Each one and look for the name configuration in a Hyper-V tree.
$HyperVList=GET-CHILDITEM C:\ProgramData –recurse –include *.XML –erroraction 'SilentlyContinue'
$Results=NEW-ITEM C:\HyperVlist.csv –itemtype file –force
ADD-CONTENT –value $CSVHeader -path C:\HyperVlist.csv
Foreach ($file in $HyperVList)
ADD-CONTENT –value $CSVdata -path C:\HyperVlist.csv
Now when we’re done we’ll have a complete list of the Hyper-V virtual machines and their XML configuration files stored in any easy to access fashion.
Stick around. Tomorrow I’ll show you how to identify the configuration differences before you import.
I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Sean Kearney, Honorary Scripting Guy and Windows PowerShell MVP