December 16th, 2013

PowerShell Above and Beyond the Minimum Requirements

Doctor Scripto
Scripter

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 up with to solve the scenario. Jason Walker and Brian Wilhite, both Microsoft PFEs and Windows PowerShell enthusiasts decided that they wanted to go above and beyond the  answer that I provided. Here is Jason to kick off their effort…

Windows PowerShell doesn’t always have to be about work.  It can be about fun too.  When Ed Wilson started to show off, Brian and I jumped at the opportunity to go above and beyond the Scripting Guy.  Brian reproduced Ed’s effort, and he had the phrase “Hello World!” 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 SpVoice Interface (SAPI 5.3).

There are already scripts floating about on the web that leverage SAPI.SPVoice, but here as another example of how to use it.

First create the SAPI.SPVOICE COM object:

$Sapi = New-Object -ComObject sapi.spvoice

Now get a list of voices by calling the GetVoices method. The following three objects are returned on my computer:

Image of command output

If we look by viewing the entire value of the Id property, we see that each voice has a name. The voice names are embedded in the Tokens field. This is shown here:

Image of command output

We have voices name David, Hazel, and Zira. Hazel is British, by the way.

We can set the voice by declaring the Voice property with one of the available voice objects. Here is an example of setting the voice to Hazel:

Image of command output

Brian, how about your part?

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’d reproduce what he had done by doing the following.

First, I decided to create a function called “HelloWorld” to capture the existing $Host.UI.RawUI values so that I can set them back when I’m done:

Function HelloWorld {

$FGColor = $Host.UI.RawUI.ForegroundColor

$BGColor = $Host.UI.RawUI.BackgroundColor

$CurSize = $Host.UI.RawUI.CursorSize

$WinSize = $Host.UI.RawUI.WindowSize

Next, I set the CursorSize to a value of 0 so that it’s sort of invisible when my function is executed. I also set the “Hello World!” string to a variable named Hello:

$Host.UI.RawUI.CursorSize = 0

$Hello = “Hello World!”

So next, Jason and I decided to loop through each of the voices that are provided with a default installation of Windows 8.1 to hear them saying “Hello World!” and we bounced the text in different colors across the Windows PowerShell console. This is done with the following script:

$Sapi = New-Object -ComObject sapi.spvoice

$Sapi.GetVoices() | ForEach-Object {

So for each voice, we are grabbing two random numbers, which will represent foreground and background colors:

$a = Get-Random -Minimum 0 -Maximum 7

$b = Get-Random -Minimum 8 -Maximum 15

Here we are setting the foreground and background colors based on the random low and high range variables that we defined:

$host.UI.RawUI.ForegroundColor = $a

$host.UI.RawUI.BackgroundColor = $b

Now we clear the host and set the CursorPosition based on the WindowSize minus the 12 characters in Hello World! and add an extra space, equaling 13:

Clear-Host

$Host.UI.RawUI.CursorPosition = @{

x=(Get-Random -Minimum 0 -Maximum ($WinSize.Width -13))

y=(Get-Random -Minimum 0 -Maximum $WinSize.Height)

}

Here, you’ll see how we output the contents of the Hello variable, then use Jason’s script to “say” the string “Hello World!”, and clear the host:

$Hello

$Sapi.Voice = $_

[void]$Sapi.Speak($Hello)

Clear-Host

}## End ForEach-Object

Next, we set back the foreground and background colors to where they were before we modified their values, then clear the screen:

$Host.UI.RawUI.ForegroundColor = $FGColor

$Host.UI.RawUI.BackgroundColor = $BGColor

$Host.UI.RawUI.CursorSize = $CurSize

Clear-Host

}## End Function HelloWorld

Here are a couple of screenshots of the function in action:

Image of screen

Image of screen

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 “Hello World!”  The script is available in the Script Center Repository: HelloWorld.ps1

~Jason and Brian

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.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.