PowerShell 2.0 and later
In a previous tip we introduced an “acoustic progress bar” that made PowerShell play a sound for as long as it was busy. Here is the code again:
# find first available WAV file in Windows folder $WAVPath = Get-ChildItem -Path $env:windir -Filter *.wav -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName # load file and play it $player = New-Object Media.SoundPlayer $WAVPath $player.PlayLooping() 1..100 | ForEach-Object { Write-Progress -Activity 'Doing Something. Hang in' -Status $_ -PercentComplete $_ Start-Sleep -MilliSeconds (Get-Random -Minimum 300 -Maximum 1300) } $player.Stop()
This script works fine – unless you interrupt it, for example by pressing CTRL+C. If you do, the script immediately stops, and $player.Stop() has no chance to execute and stop the sound.
This is when you need the finally() construct in PowerShell. It guarantees that cleanup code runs before a script aborts:
# find first available WAV file in Windows folder $WAVPath = Get-ChildItem -Path $env:windir -Filter *.wav -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName # load file and play it $player = New-Object Media.SoundPlayer $WAVPath try { $player.PlayLooping() 1..100 | ForEach-Object { Write-Progress -Activity 'Doing Something' -Status $_ -PercentComplete $_ Start-Sleep -MilliSeconds (Get-Random -Minimum 300 -Maximum 1300) } } finally { $player.Stop() }