Besides using PowerShell for the usual work related things, we can also have some fun with it by tapping into various .Net classes to do things such as letting PowerShell talk to us. There are quite a few examples of this floating around and this is my turn at talking about it and showing what you can do as well as showing off one of my functions. This is also one of many articles that I have had on the backburner while working things that I felt were more important to post, but felt like I had better get this out before I wait much longer.
Back in the day, one would have looked towards using a COM object (sapi.spvoice) to make this happen. But I won’t be touching that in this article but instead will be looking at the System.Speech.Synthesis.SpeechSynthesizer class instead. At the end I will point you towards a small function that I created which will allow you to easily send data to PowerShell which will then be spoken to you.
Lets start digging into this by creating an object using the SpeechSynthesizer class. But before that, we need to add the System.Speech assembly as it is not already loaded.
Add-Type -AssemblyName System.speech
Now we can create the SpeechSynthesizer object.
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
Exploring the object, we can see that there are a few properties and many methods in this object.
$speak | Get-Member
To simply use the defaults and say something , do this using the Speak() method:
$speak.Speak("Would you like to play a game?")
Using the Speak() method blocks the console until everything has finished. If you want to free up the console as soon as you supply the string, use the SpeakAsync() method instead.
You can even save your data to a WAV file so it can be played at a later time. Before you begin using Speak() or SpeakAsyn(), first call the SetOutputToWaveFile() and supply a string showing the file path with file name.
$speak.SetOutputToWaveFile("C:\users\Administrator\Desktop\test.wav") $speak.Speak("Would you like to play a game?") $speak.Dispose()
Don’t forget call Dispose() after your final call to Speak(), otherwise you will not be able to play the WAV file.
Now that we know how to let PowerShell speak to us, lets take a look at a few things we can do to adjust settings prior to using the Speak() methods.
The first property you can look at is Volume. It does exactly what you would think: adjusts the volume that will be used when speaking. The accepted values are 0 –> 100; anything more or less will result in a error being displayed. Also note that the default value of this is 100.
Rate is another property which can easily be adjusted based on your preference. The accepted values are –10 –> 10. The default value at the time of object creation is 0. Dipping into the negative values will slow the voice down while proceeding towards 10 will speed the voice up. Give it a shot and have some fun!
By default, you get the great sound of Microsoft David Desktop talking to you when use want PowerShell to speak to you.
Depending on your OS installation and possibly other things, this may be the only voice that you have access to. I am currently running Windows Server 2012 R2 on this system and have access to other voices. You can do the following to see what voices you have available:
Well, I know that we have 3 voices, but this doesn’t provide much useful information as it what kind of voices, so lets dig deeper.
Much better! Well, besides David I have two female voices available to use. Lets go ahead and try the next in line: Microsoft Hazel Desktop. I can do this by using the SelectVoice() method and providing the full name of the voice.
$speak.SelectVoice('Microsoft Hazel Desktop')
And now we can check out the new voice:
$speak.Speak('Would you like to play a game?')
Excellent! We now have a different voice that can be used instead of Dave.
Now if you were thinking that this might be a great function, well then you are correct! I went ahead and put together a function called Out-Voice that will take pipeline input or data via the –InputObject parameter to depending on the other parameters, either speak to you or send the data to a WAV file instead.
First I will dot source the script to load the function.
And now I will have it speak the current time:
"The current time is $((Get-Date).ToShortTimeString())" | Out-Voice
You could even use this to run a scan on something and have it say something to you when it has completed. There are quite a few possibilities that you can use with this. Go out and explore!
Currently, I do not have support for the other voices, but they are planned for a future update. But until then, the function in its current form is available for download at the link below. Give it a shot and let me know what you think!