Fun and Games with PowerShell

I hadn't previously used a "do until" loop in PowerShell so I decided this was as good as an excuse as any to use one since the loop has to run at least once anyway and it gave me a chance to learn something new.

 1Add-Type -AssemblyName System.Speech
 2
 3[int]$guess = 0
 4[int]$attempt = 0
 5[int]$number = Get-Random -Minimum 1 -Maximum 100
 6
 7$voice = New-Object System.Speech.Synthesis.SpeechSynthesizer
 8$voice.Speak("Ahoy matey! I'm the Dreaded Pirate Robbins, and I have a secret!
 9              It's a number between 1 and 100. I'll give you 7 tries to guess it.")
10
11do {
12    $voice.SpeakAsync("What's your guess?") | Out-Null
13
14    try {
15        $guess = Read-Host "What's your guess?"
16
17        if ($guess -lt 1 -or $guess -gt 100) {
18            throw
19        }
20    }
21    catch {
22        $voice.Speak("Invalid number")
23        continue
24    }
25
26    if ($guess -lt $number) {
27        $voice.Speak("Too low, yee scurry dog!")
28    }
29    elseif ($guess -gt $number) {
30        $voice.Speak("Too high, yee land lubber!")
31    }
32
33    $attempt += 1
34}
35until ($guess -eq $number -or $attempt -eq 7)
36
37if ($guess -eq $number) {
38    $voice.Speak("Avast! Yee guessed my secret number, yee did!")
39}
40else {
41    $voice.Speak("Yee out of guesses! Better luck next time, yee matey!
42                  My secret number was $number")
43}

I would like to thank Jason Helmick for the tip on using the .NET Framework instead of COM for the speech as well as Rohn Edwards who originally wrote a version of the code shown below that used COM which I translated into using the .NET Framework as well:

 1#Requires -Version 3.0
 2Add-Type -AssemblyName System.Speech
 3
 4$voice = New-Object System.Speech.Synthesis.SpeechSynthesizer
 5
 6$voice.GetInstalledVoices() | ForEach-Object {
 7    if ($_.VoiceInfo.Id -match "TTS_MS_(?<culture>\w{2}-\w{2})_(?<name>[^_]+)") {
 8        $Name = $matches.name
 9        $Culture = [cultureinfo]$matches.culture | select -expand DisplayName
10    }
11    else {
12        Write-Warning "Couldn't get info from $($_.VoiceInfo.Id)"
13        $Name = "something I'm not going to share with you"
14        $Culture = "something you're not going to find out"
15    }
16
17    $voice.SelectVoice($_.voiceinfo.name)
18    $voice.Speak("Hi, my name is $Name and my speaking style is $Culture")
19}

µ