{"id":2410,"date":"2013-12-16T00:01:00","date_gmt":"2013-12-16T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/12\/16\/powershell-above-and-beyond-the-minimum-requirements\/"},"modified":"2013-12-16T00:01:00","modified_gmt":"2013-12-16T00:01:00","slug":"powershell-above-and-beyond-the-minimum-requirements","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-above-and-beyond-the-minimum-requirements\/","title":{"rendered":"PowerShell Above and Beyond the Minimum Requirements"},"content":{"rendered":"<p><strong>Summary<\/strong>: Two Microsoft Windows PowerShell experts get extreme with the standard Hello World script.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Last month at the <a href=\"http:\/\/www.meetup.com\/Charlotte-PowerShell-Users-Group\/\" target=\"_blank\">Charlotte PowerShell User Group<\/a> meeting, we played around with some scenarios, and we had each of the attendees work through the tasks to see the various ways they would come up with to solve the scenario. <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/jason+walker\/\" target=\"_blank\">Jason Walker<\/a> and <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/brian+wilhite\/\" target=\"_blank\">Brian Wilhite<\/a>, both Microsoft PFEs and Windows PowerShell enthusiasts decided that they wanted to go above and beyond the &nbsp;answer that I provided. Here is Jason to kick off their effort&hellip;<\/p>\n<p>Windows PowerShell doesn&rsquo;t always have to be about work.&nbsp; It can be about fun too.&nbsp; When Ed Wilson started to show off, Brian and I jumped at the opportunity to go above and beyond the Scripting Guy.&nbsp; Brian reproduced Ed&rsquo;s effort, and he had the phrase &ldquo;Hello World!&rdquo; bouncing around the Windows PowerShell console and changing colors in the process. I thought it would be cool if it could actually say the phrase and change voice each time. I called to action <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms723602(v=vs.85).aspx\" target=\"_blank\">SpVoice Interface (SAPI 5.3)<\/a>.<\/p>\n<p>There are already scripts floating about on the web that leverage SAPI.SPVoice, but here as another example of how to use it.<\/p>\n<p>First create the SAPI.SPVOICE COM object:<\/p>\n<p style=\"padding-left: 30px\">$Sapi = New-Object -ComObject sapi.spvoice<\/p>\n<p>Now get a list of voices by calling the <strong>GetVoices<\/strong> method. The following three objects are returned on my computer:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6607.hsg-12-16-13-1.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6607.hsg-12-16-13-1.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>If we look by viewing the entire value of the <strong>Id<\/strong> property, we see that each voice has a name. The voice names are embedded in the <strong>Tokens<\/strong> field. This is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0066.hsg-12-16-13-2.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0066.hsg-12-16-13-2.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>We have voices name David, Hazel, and Zira. Hazel is British, by the way.<\/p>\n<p>We can set the voice by declaring the <strong>Voice<\/strong> property with one of the available voice objects. Here is an example of setting the voice to Hazel:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2337.hsg-12-16-13-3.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2337.hsg-12-16-13-3.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>Brian, how about your part?<\/p>\n<p>Thanks Jason, it was a rather fun night at the Charlotte PowerShell User Group. Because the Scripting Guy was quick to show off his creation, I figured I&rsquo;d reproduce what he had done by doing the following.<\/p>\n<p>First, I decided to create a function called &ldquo;HelloWorld&rdquo; to capture the existing <strong>$Host.UI.RawUI<\/strong> values so that I can set them back when I&rsquo;m done:<\/p>\n<p style=\"padding-left: 30px\">Function HelloWorld {<\/p>\n<p style=\"padding-left: 30px\">$FGColor = $Host.UI.RawUI.ForegroundColor<\/p>\n<p style=\"padding-left: 30px\">$BGColor = $Host.UI.RawUI.BackgroundColor<\/p>\n<p style=\"padding-left: 30px\">$CurSize = $Host.UI.RawUI.CursorSize<\/p>\n<p style=\"padding-left: 30px\">$WinSize = $Host.UI.RawUI.WindowSize<\/p>\n<p>Next, I set the <strong>CursorSize<\/strong> to a value of 0 so that it&rsquo;s sort of invisible when my function is executed. I also set the &ldquo;Hello World!&rdquo; string to a variable named <strong>Hello<\/strong>:<\/p>\n<p style=\"padding-left: 30px\">$Host.UI.RawUI.CursorSize = 0<\/p>\n<p style=\"padding-left: 30px\">$Hello = &#8220;Hello World!&#8221;<\/p>\n<p>So next, Jason and I decided to loop through each of the voices that are provided with a default installation of Windows&nbsp;8.1 to hear them saying &ldquo;Hello World!&rdquo; and we bounced the text in different colors across the Windows PowerShell console. This is done with the following script:<\/p>\n<p style=\"padding-left: 30px\">$Sapi = New-Object -ComObject sapi.spvoice<\/p>\n<p style=\"padding-left: 30px\">$Sapi.GetVoices() | ForEach-Object {<\/p>\n<p>So for each voice, we are grabbing two random numbers, which will represent foreground and background colors:<\/p>\n<p style=\"padding-left: 30px\">$a = Get-Random -Minimum 0 -Maximum 7<\/p>\n<p style=\"padding-left: 30px\">$b = Get-Random -Minimum 8 -Maximum 15<\/p>\n<p>Here we are setting the foreground and background colors based on the random low and high range variables that we defined:<\/p>\n<p style=\"padding-left: 30px\">$host.UI.RawUI.ForegroundColor = $a<\/p>\n<p style=\"padding-left: 30px\">$host.UI.RawUI.BackgroundColor = $b<\/p>\n<p>Now we clear the host and set the <strong>CursorPosition<\/strong> based on the <strong>WindowSize<\/strong> minus the 12 characters in <strong>Hello World!<\/strong> and add an extra space, equaling 13:<\/p>\n<p style=\"padding-left: 30px\">Clear-Host<\/p>\n<p style=\"padding-left: 30px\">$Host.UI.RawUI.CursorPosition = @{<\/p>\n<p style=\"padding-left: 30px\">x=(Get-Random -Minimum 0 -Maximum ($WinSize.Width -13))<\/p>\n<p style=\"padding-left: 30px\">y=(Get-Random -Minimum 0 -Maximum $WinSize.Height)<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p>Here, you&rsquo;ll see how we output the contents of the <strong>Hello<\/strong> variable, then use Jason&rsquo;s script to &ldquo;say&rdquo; the string &ldquo;Hello World!&rdquo;, and clear the host:<\/p>\n<p style=\"padding-left: 30px\">$Hello<\/p>\n<p style=\"padding-left: 30px\">$Sapi.Voice = $_<\/p>\n<p style=\"padding-left: 30px\">[void]$Sapi.Speak($Hello)<\/p>\n<p style=\"padding-left: 30px\">Clear-Host<\/p>\n<p style=\"padding-left: 30px\">}## End ForEach-Object<\/p>\n<p>Next, we set back the foreground and background colors to where they were before we modified their values, then clear the screen:<\/p>\n<p style=\"padding-left: 30px\">$Host.UI.RawUI.ForegroundColor = $FGColor<\/p>\n<p style=\"padding-left: 30px\">$Host.UI.RawUI.BackgroundColor = $BGColor<\/p>\n<p style=\"padding-left: 30px\">$Host.UI.RawUI.CursorSize = $CurSize<\/p>\n<p style=\"padding-left: 30px\">Clear-Host<\/p>\n<p style=\"padding-left: 30px\">}## End Function HelloWorld<\/p>\n<p>Here are a couple of screenshots of the function in action:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7345.hsg-12-16-13-4.png\"><img decoding=\"async\" title=\"Image of screen\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7345.hsg-12-16-13-4.png\" alt=\"Image of screen\" \/><\/a><\/p>\n<p style=\"padding-left: 60px\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6175.hsg-12-16-13-5.png\"><img decoding=\"async\" title=\"Image of screen\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6175.hsg-12-16-13-5.png\" alt=\"Image of screen\" \/><\/a><\/p>\n<p>As you can see, Jason and I (in our opinion) went above and beyond what Ed suggested as the most creative way to script the traditional &ldquo;Hello World!&rdquo; &nbsp;The script is available in the Script Center Repository:&nbsp;<a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/1-Upping-The-Scripting-Guy-ef5748b9\" target=\"_blank\">HelloWorld.ps1<\/a><\/p>\n<p>~Jason and Brian<\/p>\n<p>I love it when I introduce an idea and other scripters run with it to see how far they can go. It is a true joy to watch these guys work together and see their ideas. Thank you, Jason and Brian.<\/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><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Two Microsoft Windows PowerShell experts get extreme with the standard Hello World script. Microsoft Scripting Guy, Ed Wilson, is here. Last month at the Charlotte PowerShell User Group meeting, we played around with some scenarios, and we had each of the attendees work through the tasks to see the various ways they would come [&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":[327,25,56,338,3,4,45],"class_list":["post-2410","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-brian-wilhite","tag-displaying-output","tag-guest-blogger","tag-jason-walker","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Two Microsoft Windows PowerShell experts get extreme with the standard Hello World script. Microsoft Scripting Guy, Ed Wilson, is here. Last month at the Charlotte PowerShell User Group meeting, we played around with some scenarios, and we had each of the attendees work through the tasks to see the various ways they would come [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2410","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=2410"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2410\/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=2410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}