{"id":2735,"date":"2013-10-14T00:01:00","date_gmt":"2013-10-14T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/10\/14\/recovering-virtual-machines-in-hyper-v-server-2012-r2-part-1\/"},"modified":"2013-10-14T00:01:00","modified_gmt":"2013-10-14T00:01:00","slug":"recovering-virtual-machines-in-hyper-v-server-2012-r2-part-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/recovering-virtual-machines-in-hyper-v-server-2012-r2-part-1\/","title":{"rendered":"Recovering Virtual Machines in Hyper-V Server 2012 R2: Part 1"},"content":{"rendered":"<p><strong>Summary<\/strong>: Use Windows PowerShell to find your virtual machines in a recovered file system.<\/p>\n<p align=\"left\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" \/>&nbsp;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&nbsp;2012&nbsp;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!<\/p>\n<p>&mdash;AJ<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" \/>&nbsp;Hello AJ,<\/p>\n<p>Honorary Scripting Guy, Sean Kearney here&mdash;filling in for our good friend Ed. He&rsquo;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.<\/p>\n<p>So with Hyper-V in Windows Server&nbsp;2008 through Windows Server&nbsp;2012&nbsp;R2, the configuration data has always been stored in an .xml file.<\/p>\n<p>Oh good! Done. Hey, Scripting Guy! Blog post complete! We&rsquo;ll run:<\/p>\n<p style=\"padding-left: 30px\">GET-CHILDITEM &ndash;recurse &ndash;include *.XML &ndash;force<\/p>\n<p>And poke through the pile. WooHoo!<\/p>\n<p>Yes. We could do that. But that would be pretty pointless, wouldn&rsquo;t it? XML is not only used by Hyper-V, it&rsquo;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.<\/p>\n<p>That&rsquo;s absolutely fine if you enjoy doing that&mdash;everybody has to have a hobby.<\/p>\n<p>I particularly enjoy finding a way for the computer to do the work for me. So let&rsquo;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.<\/p>\n<p>To pull it&rsquo;s configuration so we can look at it, we need to run <strong>Get-Content<\/strong> against the item and store in a strong type <strong>[XML]<\/strong> variable:<\/p>\n<p style=\"padding-left: 30px\">[XML]$HyperVConfig=GET-CONTENT C:\\VM\\TestDC\\TestDC\\Virtual Machines\\C32AFB36-F9BB-4001-98C1-D2CBE8AD26CD.xml<\/p>\n<p>After it is stored, we can examine the properties that are unique to a Hyper-V virtual machine. The one we&rsquo;re going to be concerned with is the <strong>DisplayName<\/strong> of the virtual machine. It&rsquo;s stored in the XML tree under <strong>Configuration.Properties.Name<\/strong>:<\/p>\n<p style=\"padding-left: 30px\">$HyperVConfig.configuration.properties.name<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5658.1.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5658.1.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>By looking at this file, we see there is a property call <strong>#text<\/strong>, which contains the name of our virtual machine. Even though its file name is written in some type of Klingon (sorry, that&rsquo;s what a GUID looks like to me), we can identify the virtual machine for this configuration.<\/p>\n<p>But if we try to access this property by its name, the console will prompt us for more information, as you see here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0407.2.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0407.2.png\" alt=\"Image of command output\" width=\"399\" height=\"54\" \/><\/a><\/p>\n<p>That&rsquo;s because the &ldquo;<strong>#<\/strong>&rdquo; is special to the Windows PowerShell interpreter. So we need to tell the console, &ldquo;Hey! All of this belongs to me. Don&rsquo;t you dare try to interpret it!&rdquo; We can do this simply enough by enclosing it within quotes like this:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4722.3.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4722.3.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>Pretty cool, eh?<\/p>\n<p>The other piece we&rsquo;ll watch for are properties that are unique to virtual machines, such as the &ldquo;Last Powered-On Time.&rdquo; There are other .xml files owned by Hyper-V that have the <strong>#text<\/strong> 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.<\/p>\n<p>Armed with this information, we can build a pretty simple and cool script that will do three things:<\/p>\n<ul>\n<li>Identify the .xml files that are virtual machine configurations for Hyper-V<\/li>\n<li>Display the name<\/li>\n<li>Store it in a .csv file<\/li>\n<\/ul>\n<p>For this script, I&rsquo;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.<\/p>\n<p>First get all potential .xml files:<\/p>\n<p style=\"padding-left: 30px\">$HyperVList=GET-CHILDITEM C:\\ProgramData &ndash;recurse &ndash;include *.XML &ndash;erroraction &lsquo;SilentlyContinue&rsquo;<\/p>\n<p>Next we get the content of Each one and look for the name configuration in a Hyper-V tree.<\/p>\n<p style=\"padding-left: 30px\">$HyperVList=GET-CHILDITEM C:\\ProgramData &ndash;recurse &ndash;include *.XML &ndash;erroraction &#8216;SilentlyContinue&#8217;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$Results=NEW-ITEM C:\\HyperVlist.csv &ndash;itemtype file &ndash;force<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$CSVHeader='&#8221;Name&#8221;,&#8221;XMLFile&#8221;&#8216;<\/p>\n<p style=\"padding-left: 30px\">ADD-CONTENT &ndash;value $CSVHeader -path C:\\HyperVlist.csv<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Foreach ($file in $HyperVList)<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [XML]$HyperVConfig=GET-CONTENT $File.Fullname<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $VmTest=$HyperVConfig.configuration.properties.last_powered_on_time<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If ($VMTest)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ConfigName=$HyperVConfig.configuration.properties.name.&#8217;#text&#8217;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $CSVData='&#8221;&#8216;+$Configname+'&#8221;,&#8221;&#8216;+$File.Fullname+'&#8221;&#8216;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADD-CONTENT &ndash;value $CSVdata -path C:\\HyperVlist.csv<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p>Now when we&rsquo;re done we&rsquo;ll have a complete list of the Hyper-V virtual machines and their XML configuration files stored in any easy to access fashion.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5037.4.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5037.4.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>Stick around. Tomorrow I&rsquo;ll show you how to identify the configuration differences before you import.<\/p>\n<p>~Sean&nbsp;&nbsp; &nbsp;<\/p>\n<p>I invite you to follow the Scripting Guys on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Sean Kearney<\/strong>, Honorary Scripting Guy and Windows PowerShell MVP&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Use Windows PowerShell to find your virtual machines in a recovered file system. &nbsp;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&nbsp;2012&nbsp;R2 environment. Can you tell me if there is [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,271,3,154,45],"class_list":["post-2735","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-hyper-v","tag-scripting-guy","tag-sean-kearney","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Use Windows PowerShell to find your virtual machines in a recovered file system. &nbsp;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&nbsp;2012&nbsp;R2 environment. Can you tell me if there is [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2735","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=2735"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2735\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=2735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}