{"id":198,"date":"2014-12-15T00:01:00","date_gmt":"2014-12-15T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/12\/15\/start-virtual-machines-in-order-and-wait-for-stabilization\/"},"modified":"2019-02-18T10:36:33","modified_gmt":"2019-02-18T17:36:33","slug":"start-virtual-machines-in-order-and-wait-for-stabilization","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/start-virtual-machines-in-order-and-wait-for-stabilization\/","title":{"rendered":"Start Virtual Machines in Order and Wait for Stabilization"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Microsoft Scripting Guy, Ed Wilson, talks about using a Windows PowerShell workflow to ensure that virtual machines start in order and stabilize.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Last month, I wrote the following blog post: <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-start-or-stop-virtual-machines-in-order\/\" target=\"_blank\">Use PowerShell to Start or Stop Virtual Machines in Order<\/a>. The workflow worked great. The problem is that some of the virtual machines take a while to stabilize after they are running. This means that when I start virtual machines in a specific order, there needs to be a bit of a delay from the time the virtual machine is running to the time that I can sign in or connect to it from a remote machine.<\/p>\n<p>I spent a lot of time working on a modification to the script. After I finished my script, I sent it to some people on the Windows PowerShell team to see if I was on the right track. Although my script worked great, it was&#8230;well&#8230;somewhat of a FrankenScript. I thought the code was confusing and downright ugly.<\/p>\n<p>In a few minutes, Lee Holmes had cleaned up the script by simplifying it dramatically.<\/p>\n<p>The main problem with my previous script is that when a virtual machine starts, it takes a while (depending on the machine) before it is actually usable. However, as far as <b>Start-VM<\/b> and the Windows PowerShell workflow are concerned, when the virtual machine is started, the particular activity is completed.<\/p>\n<p>In my playing around, I noticed that there is a property called <b>Heartbeat<\/b><i> <\/i>from the virtual machine object. If it has a value of <b>OkApplicationsHealthy<\/b>, the virtual machine is perfectly usable.<\/p>\n<p style=\"margin-left:30px\"><b>Note <\/b>&nbsp;This value is not present on a virtual machine running Windows 7 unless Virtual Machine Integration Services is updated to the latest bits.<\/p>\n<p>To check for changes to the <b>Heartbeat<\/b><i> <\/i>property, I need to do a bit of polling. However, directly inside a Windows PowerShell workflow, I cannot use a <b>While<\/b> loop. So I solved the problem by using an <b>InlineScript<\/b> activity.<\/p>\n<p>This creates a new problem due to variable scoping. I had to solve that problem by using the <b>$Using<\/b> directive., and then things really get ugly. Here is the code I wrote:<\/p>\n<p>&nbsp;&nbsp;InlineScript { while (<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Get-VM -Name $using:dc1).Heartbeat -ne &#039;OkApplicationsHealthy&#039;)<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &quot;$using:dc1 not ready&#8230;&quot;; sleep 1}}<\/p>\n<p><span style=\"font-size:12px\">Like I said, it worked, but it was pretty ugly. What Lee did instead, was create a function inside the Windows PowerShell workflow. It is nice and elegant.<\/span><\/p>\n<p>The other thing I had done in my workflow was use <b>Sequence<\/b> because I wanted the virtual machines to start in a specific order. Lee suggested that it would be simpler to create an array and iterate over the array. Again, the code is cleaner.<\/p>\n<p>That represents the changes to my script, and here is the complete current script:<\/p>\n<p style=\"margin-left:30px\">workflow Start-ScenarioVM<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; function Wait-VM<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param($Name)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while((Get-VM -Name $Name).HeartBeat -ne &nbsp;&#039;OkApplicationsHealthy&#039;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start-Sleep -Seconds 1<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Verbose &quot;$name not ready. Waiting&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p>&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; foreach($vm in &#039;dc1_nwt&#039;, &#039;s1_nwt&#039;, &#039;s2_nwt&#039;, &#039;c1_nwt&#039;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start-VM -Name $vm<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Wait-VM -Name $vm<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">}<span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n<p style=\"margin-left:30px\"><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n<p style=\"margin-left:30px\">Start-ScenarioVM&nbsp;<\/p>\n<p>When I run the workflow, I see that the script pauses on the <b>Wait-VM<\/b> function in my status bar. This indicates that I am polling for a specific virtual machine. After the virtual machine starts, the script starts the next virtual machine, and once again, it will wait.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-12-15-14-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-12-15-14-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>That is all there is to using Windows PowerShell workflow to start virtual machines in order. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.<\/p>\n<p>I invite you to follow me 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 me at <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><b>Ed Wilson, Microsoft Scripting Guy<\/b><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using a Windows PowerShell workflow to ensure that virtual machines start in order and stabilize. Microsoft Scripting Guy, Ed Wilson, is here. Last month, I wrote the following blog post: Use PowerShell to Start or Stop Virtual Machines in Order. The workflow worked great. The problem 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":[3,45,382],"class_list":["post-198","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-windows-powershell","tag-workflow"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using a Windows PowerShell workflow to ensure that virtual machines start in order and stabilize. Microsoft Scripting Guy, Ed Wilson, is here. Last month, I wrote the following blog post: Use PowerShell to Start or Stop Virtual Machines in Order. The workflow worked great. The problem is [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/198","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=198"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/198\/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=198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=198"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}