Function Invoke-Notes { <# .SYNOPSIS Play some musical notes using the console beep .PARAMETER Notes The notes values to be played. Consists of three parts: Pitch, Octave (optional), NoteType (optional) Defaults to the octave "Treble C". Supports octaves from Subcontra to Five-lined (triple-high-C) Defaults to quarternotes when none are provided. .PARAMETER Tempo Speed-change for duration of notes .PARAMETER Output Debug for showing what is being calculated .NOTES Found this on Reddit, copied it down for George. Enjoy George. .LINK https://www.reddit.com/r/PowerShell/comments/q8l24k/some_powershell_beep/ .LINK https://www.reddit.com/r/PowerShell/comments/8wj4cu/i_wrote_a_powershell_script_that_uses_the_console/ .LINK https://en.wikipedia.org/wiki/C_(musical_note) .EXAMPLE # Play a G eigth note in the 6th octave # Play a F# eigth note in the 6th octave # Play a G eigth note in the 6th octave Invoke-Notes -Notes "G6E,F#6E,G6E" -Output #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Notes, [Parameter(Mandatory = $false)] [int]$Tempo, [Parameter(Mandatory = $false)] [switch]$Output = $false ) $tempoModifier = 1 $defaultNoteType = 'Q' $defaultOctave = 5 if ($Tempo -gt 0) { $tempoModifier = 100.0/$Tempo } elseif ($Tempo -lt 0) { Write-Warning "Tempo value supplied [$Tempo] is invalid (less than zero). It is ignored." } # W = Whole, H = Half, Q = Quarter, E = Eighth, S = Sixteenth $NoteTypes = [PSCustomObject]@{ 'W' = 1600 'W.' = 2000 'H' = 800 'H.' = 1000 'Q' = 400 'Q.' = 600 'E' = 200 'E.' = 300 'S' = 100 'S.' = 150 } # Define the Subcontra octave frequencies # We will calculate more octaves based from these $NoteIndex = [PSCustomObject]@{ 'C' = @(16.3516) 'C#' = @(17.32391) 'D' = @(18.35405) 'Eb' = @(19.44544) 'E' = @(20.60172) 'F' = @(21.82676) 'F#' = @(23.12465) 'G' = @(24.49971) 'G#' = @(25.95654) 'A' = @(27.50000) 'Bb' = @(29.13524) 'B' = @(30.86771) <#Rest#>'R' = 0 } foreach($note in $NoteIndex.PSObject.Properties.Name) { $seed = $NoteIndex.$note[0] $newValues = @([Math]::Round($seed,2)) # calculate 8 more octaves above the seed data foreach($mult in 0..7) { # this is the operation for 2^x -> (2 -shl $mult) $newValues += [Math]::Round( ($seed * (2 -shl $mult)) ,2) } $noteIndex.$note = $newValues } $splitNotes = ($Notes -split ',') foreach ($Note in $splitNotes) { $Note -match '(?[A-G][#|b]?|[R])(?[0-8])?(?[Ww|Hh|Qq|Ee|Ss][\.]?)?' | Out-Null $Pitch = $matches['Pitch'] $noteType = $matches['NoteType'] $octave = $matches['Octave'] if ($null -eq $noteType) { $noteType = $defaultNoteType } if ($null -eq $octave) { $octave = $defaultOctave } [int]$Duration = $tempoModifier * ($NoteTypes.$noteType) [int]$Frequency = $NoteIndex.$Pitch[$octave] if ($Output) { Write-Host "$Pitch $octave $noteType - $Duration - $Frequency" } if ($Pitch -eq 'R') { Start-Sleep -Milliseconds $Duration } else { [Console]::beep($Frequency,$Duration) } } }