In PowerShell, you can play a sound file using the `System.Media.SoundPlayer` class, as shown in the snippet below:
$player = New-Object System.Media.SoundPlayer 'C:\path\to\your\soundfile.wav'; $player.PlaySync();
Understanding Sound in PowerShell
What is PowerShell?
PowerShell is a powerful scripting language and command-line shell designed specifically for system administrators and power users. It allows users to automate tasks and manage system configurations efficiently. One of the many capabilities of PowerShell is the ability to interact with system-level components, such as sound.
Why Use Sound in Scripts?
Incorporating sound notifications into your scripts can significantly enhance the user experience. Whether you need alerts for completed processes or warnings for errors, audio cues can draw attention effectively. Imagine a script that performs automated tasks throughout the day; a sound alert can notify you when specific conditions arise, making your workflow smoother and more efficient.
Mastering PowerShell LastIndexOf: Find String Positions Easily
Playing Sounds with PowerShell
Overview of Sound File Formats
When dealing with audio in PowerShell, it’s essential to understand compatible sound file formats. The most commonly used format, .wav, is recommended because it is natively supported and offers fast playback without conversion delays. While .mp3 files can be used, they may require additional handling and libraries.
Built-in Methods to Play Sounds in PowerShell
Using the `System.Media.SoundPlayer`
The `System.Media.SoundPlayer` class provides a straightforward way to play sound files. It is primarily designed for `.wav` files and offers two main methods for playback: Play() (asynchronous) and PlaySync() (synchronous).
Example:
$player = New-Object System.Media.SoundPlayer
$player.SoundLocation = "C:\Path\To\Your\Sound.wav"
$player.PlaySync() # Plays the sound synchronously
In this example, the sound file specified by SoundLocation will play until it completes before the script continues execution. If you want the script to continue running while the sound plays, use Play() instead.
Utilizing Windows Media Player COM Object
Another method for playing sounds in PowerShell is by using the Windows Media Player COM object. This is versatile because it can handle multiple audio formats, including `.mp3`.
Example:
$wmp = New-Object -ComObject WMPlayer.OCX
$wmp.URL = "C:\Path\To\Your\Sound.mp3"
$wmp.controls.play()
In this case, we’ve created an instance of Windows Media Player and specified the URL of the sound file. $wmp.controls.play() allows for additional controls over playback, such as pause, stop, and volume adjustments.
Mastering the Art of PowerShell Round Commands
Advanced Sound Playback Techniques
Creating a Sound Notification System
Incorporating a sound notification system adds significant functionality to your scripts, particularly for monitoring tasks. For example, imagine a PowerShell script that continuously checks for a running process and alerts you with sound when it finds it.
Example Implementation:
if (Get-Process "notepad" -ErrorAction SilentlyContinue) {
$player.PlaySync()
}
In this snippet, the script checks if Notepad is running. If it is, the sound will play, effectively notifying you without needing constant checks visually.
Scheduling Sound Alerts with Task Scheduler
You can enhance your automation further by scheduling sound alerts with Windows Task Scheduler. By creating a task that triggers the playback of a sound file at specific intervals or based on system events, you can ensure that you receive notifications aligned with your workflow.
Unlocking Password Last Set with PowerShell Magic
Troubleshooting Sound Playback Issues
Common Problems and Solutions
When implementing sound playback in PowerShell scripts, several common issues may arise:
- No sound output: This often occurs due to incorrect path specifications or volume settings. Ensure the file path is correct and check your system’s volume settings.
- File type not supported: PowerShell typically supports `.wav` files natively. If you’re using another format, it’s advisable to convert them to `.wav`.
Debugging Sound Playback with PowerShell
Effective debugging can save a lot of time during development. Implement Try-Catch blocks in your scripts to handle any errors gracefully:
Example:
try {
$player = New-Object System.Media.SoundPlayer
$player.SoundLocation = "C:\Path\To\Your\Sound.wav"
$player.PlaySync()
} catch {
Write-Host "An error occurred: $_"
}
This snippet captures any exceptions and outputs them to the console, helping you identify issues quickly.
Quick Guide to Powershell PasswordExpired Command
Best Practices for Sound in PowerShell Scripts
Choosing the Right Sound Files
When integrating sound, it’s crucial to choose files that are appropriate for the context. Sound files should be short and clear—long or annoying sounds can disrupt productivity. Aim for audio cues that are noticeable but not intrusive.
Documenting Sound Usage in Scripts
Proper documentation enhances the maintainability of your scripts. Including comments that explain why a sound is played or what event triggers it is beneficial for anyone who may work with your code in the future.
Example of well-documented sound playback code:
# Check for Notepad process and play alert sound if found
if (Get-Process "notepad" -ErrorAction SilentlyContinue) {
$player.SoundLocation = "C:\Path\To\Your\AlertSound.wav"
$player.PlaySync() # Alert sound for user notification
}
Retrieve LastLogonDate with PowerShell Effortlessly
Conclusion
Integrating sound playback into your PowerShell scripts can elevate functionality and provide essential notifications in your automated workflows. From alerting you to system changes to enhancing the interactivity of your scripts, using PowerShell play sound features effectively can lead to a more efficient user experience.
Mastering PowerShell Array Count: A Simple Guide
Call to Action
Experiment with your own scripts to incorporate sound notifications. Don’t hesitate to share your scripts or ask questions! For further resources, tutorials, or specialized training in PowerShell, explore our offerings designed to empower your scripting capabilities.
Function Start-MediaPlayer
{
[cmdletbinding()]
Param(
[Alias(‘P’)] [String] $Path,
[Alias(‘Sh’)] [switch] $Shuffle,
[Alias(‘St’)] [Switch] $Stop,
[Alias(‘L’)] [Switch] $Loop
)
If($Stop)
{
Write-Verbose «Stoping any Already running instance of Media in background.»
Get-Job MusicPlayer -ErrorAction SilentlyContinue | Remove-Job -Force
}
Else
{
#Caches Path for next time in case you don’t enter path to the music directory
If($path)
{
$Path | out-file C:\Temp\Musicplayer.txt
}
else
{
If((cat C:\Temp\Musicplayer.txt -ErrorAction SilentlyContinue).Length -ne 0)
{
Write-Verbose «You’ve not provided a music directory, looking for cached information from Previous use.»
$path = cat C:\Temp\Musicplayer.txt
If(-not (Test-Path $Path))
{
«Please provide a path to a music directory.`nFound a cached directory `»$Path`» from previous use, but that too isn’t accessible!»
# Mark Path as Empty string, If Cached path doesn’t exist
$Path = »
}
}
else
{
«Please provide a path to a music directory.»
}
}
#initialization Script for back ground job
$init = {
# Function to calculate duration of song in Seconds
Function Get-SongDuration($FullName)
{
$Shell = New-Object -COMObject Shell.Application
$Folder = $shell.Namespace($(Split-Path $FullName))
$File = $Folder.ParseName($(Split-Path $FullName -Leaf))
[int]$h, [int]$m, [int]$s = ($Folder.GetDetailsOf($File, 27)).split(«:»)
$h*60*60 + $m*60 +$s
}
# Function to Notify Information balloon message in system Tray
Function Show-NotifyBalloon($Message)
{
[system.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’) | Out-Null
$Global:Balloon = New-Object System.Windows.Forms.NotifyIcon
$Balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Process -id $pid | Select-Object -ExpandProperty Path))
$Balloon.BalloonTipIcon = ‘Info’
$Balloon.BalloonTipText = $Message
$Balloon.BalloonTipTitle = ‘Now Playing’
$Balloon.Visible = $true
$Balloon.ShowBalloonTip(1000)
}
Function PlayMusic($path, $Shuffle, $Loop)
{
# Calling required assembly
Add-Type -AssemblyName PresentationCore
# Instantiate Media Player Class
$MediaPlayer = New-Object System.Windows.Media.Mediaplayer
# Crunching the numbers and Information
$FileList = gci $Path -Recurse -Include *.mp* | select fullname, @{n=’Duration’;e={get-songduration $_.fullname}}
$FileCount = $FileList.count
$TotalPlayDuration = [Math]::Round(($FileList.duration | measure -Sum).sum /60)
# Condition to identifed the Mode chosed by the user
if($Shuffle)
{
$Mode = «Shuffle»
$FileList = $FileList | Sort-Object {Get-Random} # Find the target Music Files and sort them Randomly
}
Else
{
$Mode = «Sequential»
}
# Check If user chose to play songs in Loop
If($Loop)
{
$Mode = $Mode + » in Loop»
$TotalPlayDuration = «Infinite»
}
If($FileList)
{
»| select @{n=’TotalSongs’;e={$FileCount};},@{n=’PlayDuration’;e={[String]$TotalPlayDuration + » Mins»}},@{n=’Mode’;e={$Mode}}
}
else
{
«No music files found in directory `»$path`» .»
}
Do
{
$FileList |%{
$CurrentSongDuration= New-TimeSpan -Seconds (Get-SongDuration $_.fullname)
$Message = «Song : «+$(Split-Path $_.fullname -Leaf)+»`nPlay Duration : $($CurrentSongDuration.Minutes) Mins $($CurrentSongDuration.Seconds) Sec`nMode : $Mode»
$MediaPlayer.Open($_.FullName) # 1. Open Music file with media player
$MediaPlayer.Play() # 2. Play the Music File
Show-NotifyBalloon ($Message) # 3. Show a notification balloon in system tray
Start-Sleep -Seconds $_.duration # 4. Pause the script execution until song completes
$MediaPlayer.Stop() # 5. Stop the Song
$Balloon.Dispose();$Balloon.visible =$false
}
}While($Loop) # Play Infinitely If ‘Loop’ is chosen by user
}
}
# Removes any already running Job, and start a new job, that looks like changing the track
If($(Get-Job Musicplayer -ErrorAction SilentlyContinue))
{
Get-Job MusicPlayer -ErrorAction SilentlyContinue |Remove-Job -Force
}
# Run only if path was Defined or retrieved from cached information
If($Path)
{
Write-Verbose «Starting a background Job to play Music files»
Start-Job -Name MusicPlayer -InitializationScript $init -ScriptBlock {playmusic $args[0] $args[1] $args[2]} -ArgumentList $path, $Shuffle, $Loop | Out-Null
Start-Sleep -Seconds 3 # Sleep to allow media player some breathing time to load files
Receive-Job -Name MusicPlayer | ft @{n=’TotalSongs’;e={$_.TotalSongs};alignment=’left’},@{n=’TotalPlayDuration’;e={$_.PlayDuration};alignment=’left’},@{n=’Mode’;e={$_.Mode};alignment=’left’} -AutoSize
}
}
}
Stange bedfellows you might think but why shouldn’t media be scripted ?
I was thinking this a couple of weeks ago. I wanted to run a video before I started a presentation. If the Presentation is due to start at 10:00, and the video is 3 minutes I want to the video to start automatically at 9:57, and step onto the stage at 10:00 exactly as it finishes. I cobbled something together to do that but I didn’t like it. Actually I want to play music before the video. I want a play list of tracks to start at the right time, I want the last one to fade out and go into the video. If people are in their seats before the video starts I want something counting down on screen. Etc.
Now Windows Media Player has an object model and I’ve used it before so how hard could it be ? It turned out to be a little harder than I thought because the object I used in a bit of VB.net aeons ago doesn’t seem to like running in PowerShell. I found Saveen was using a different object so I typed in
$wmp = New-object –COM WMPlayer.OCX
and I was away… but compared with other things I have worked with recently the Object model is – backward is the nicest word I can use. I can get a play list and I’d expect to be able to do “For each item in list.tracks”. But no: you have to go call list.item(track Number) for each track. To get a playlist you have to request it by name from the “playlist collection” object. You have to specify the exact name – no wild cards. Yet it comes back as a collection, which again doesn’t work with forEach. Grrr. So I wrote a function to get a playlist.
Function get-Playlist
{param ($Name)
if ($Name -eq $null) {$wmp.currentPlayList}
else {$list=$wmp.playlistCollection.getByName($Name) 0..($list.count - 1)|foreach {$list.item($_) } }
}
If the name isn’t specified the function returns the currently playing list, otherwise it gets the named list, and it outputs each list found. All 1 of them.
Next came Set-Playlist – I wanted to be able to do Set-PlayList $listObject or set-playlist “random” or get-Playlist “random” | set-playlist so this became a filter
filter Set-Playlist
{param ($Playlist)
if ($playlist -eq $null) {$playList=$_}
if ($playlist -is [string]) {$playlist=get-playlist $playList}
if ($Playlist -is [system.__ComObject]) {$WMP.currentPlaylist = $playlist}
}
Of Course I wanted to see the tracks in a play list so that became the next function – again set up to take Piped input, or a name or an object
filter get-MediaInPlaylist
{param ($Playlist)
if ($playlist -eq $null) {$playList=$_}
if ($playlist -is [string]) {$playlist=Get-Playlist $playList}
if ($playlist -eq $null) {$playList=$wmp.currentPlayList}
0..($Playlist.count - 1) | foreach {$playlist.item($_) }
$playlist=$null
}
Getting media which is not in an existing play list involves a query to the mediaCollection object there is get media by name, get media by artist and get media by album. It turns out that any attempt to get media returns a playlist, I could have left it that way and te results could be piped into set-playlist but I wanted to see the tracks, so that was how I built the next function.
function get-media
{param ($Name, [Switch]$album, [Switch]$artist)
if ($artist) {$wmp.mediaCollection.getByAuthor($Name)| get-MediaInPlaylist }
elseif ($album) {$wmp.mediaCollection.getByAlbum($Name) | get-MediaInPlaylist }
else {$wmp.mediaCollection.GetByName($name) | get-MediaInPlaylist }
}
There’s also a get media by attribute so you can say “Find me all files where the format is MP3.”
function get-mediaByAttribute
{param ($attribute, $value)
$wmp.mediaCollection.getByAttribute($Attribute,$value) | get-MediaInPlaylist }
Next I wanted to be able to add the items I’d just found to the current playlist – so in came Append media, and to make sure I could start with an empty list so did Reset-Media.
filter Append-Media
{param ($item , $Playlist)
if ($Item -eq $null) {$Item=$_}
if ($playlist -is [string]) {$playlist=get-playlist $playList}
if ($playlist -eq $null) {$playList=$wmp.currentPlayList}
$playList.appendItem($item)
$item=$null }
Function reset-media {$wmp.currentPlaylist=$wmp.newPlaylist("Playlist","") }
Finally (for now ) came starting and stopping the playlist.
Function Start-media {$wmp.controls.play() }
Function Stop-media {$wmp.controls.stop() }Function Pause-media {$wmp.controls.pause() }
In the next post I’ll look at waiting for the media to do things, fading music up and down, why this is no good for video and what to do about it.
This post originally appeared on my technet blog.
Posted: June 16, 2023 in Scripts
In case you often need to add files to WMP playlist or any other XML file, take a look at this script
WMP has below format, which means new files should be added below <seq>
tag
- Script first checks if there are any mp3 file in Downloads folder, and will move it to location where other mp3 files are stored
- Script then will check if there is already file where is stored last time when script was running, and if yes, it will look for files which were added after script was ran last time, obviously, if script runs for the first time, that file won’t be present, in that case, script would scan all MP3 files in the directory and will check if file name is missing from the playlist and will try to add it.
- At the end, script will add “marker” so it won’t scan all files, but only those created after script was run last time
$mp3Path = "C:\Istorija\" $playList = "C:\Users\user\Music\Playlists\1.wpl" $mp3DownloadPath = "C:\Users\user\Downloads\" $scriptRunLastTimePath = "$mp3Path\date.txt" $directoryInfo = Get-ChildItem -Path $mp3DownloadPath -Filter "*.mp3" -File | Measure-Object # If any mp3 file in Download folder, move it to $mp3Path $count = $directoryInfo.Count Try{ if($count -eq 0){ Write-Host "Nothing to move to $mp3Path" -ForegroundColor Magenta } else{ Get-ChildItem -Path $mp3DownloadPath -Filter "*.mp3" -Recurse -File | Move-Item -Destination $mp3Path -Force } } Catch{ $Error[0] } # If File with datetime when script was executed exists, get mp3 files created after script ran last time and store them in the $mp3Files variable Try{ if (Test-Path $scriptRunLastTimePath -PathType Leaf) { $dateToCompareWith = Get-Content -Path $scriptRunLastTimePath $culture = [System.Globalization.CultureInfo]::InvariantCulture $format = 'dd.MM.yyyy HH:mm:ss' $storedDateTime = [DateTime]::ParseExact($dateToCompareWith, $format, $culture) $mp3Files = @(Get-ChildItem -Path $mp3Path -Filter "*.mp3" -File | Where-Object { $_.LastWriteTime -gt $storedDateTime }) } else { $mp3Files = Get-ChildItem -Path $mp3Path -Filter "*.mp3" -File } } Catch{ $Error[0] } # Get current files in playlist ($xml = [xml]::new()).Load($playList) $currentFilesInPlaylist = $xml.SelectNodes("//seq/*").src # If mp3 file is present in folder and not in 1.wpl, add the full file name to playlist file after the <seq> tag foreach ($mp3File in $mp3Files) { Try{ # Note the use of -notin and the *whole array* of files in the playlist. if ($mp3File.FullName -notin $currentFilesInPlaylist) { (Get-Content $playlist) | Foreach-Object { $_ # send the current line to output if ($_ -match "<seq>") { # Add lines after the selected pattern ' <media src="' + $mp3File.FullName + '"/>' } } | Set-Content $playList -Force $output = "File " + $mp3File.FullName + " has been added to playlist" Write-Host $output -ForegroundColor Magenta } else { Write-Host "Nothing to add" -ForegroundColor Green } } Catch{ $Error[0] } } # Create a "checkpoint" file: Export the date and time the script was last run to the file (Get-Date).ToString('dd/MM/yyyy HH:mm:ss') | Out-File -FilePath $scriptRunLastTimePath
This tutorial will show you how to install or uninstall the «Windows Media Player Legacy» app for all users in Windows 11.
Windows 11 includes the new Windows Media Player app from the Microsoft Store by default.
Windows 11 also includes the old Windows Media Player Legacy desktop app if you prefer to use it instead of the newer Media Player app.
The Windows Media Player Legacy EXE file is located at: «C:\Program Files (x86)\Windows Media Player\wmplayer.exe»
Reference:
You must be signed in as an administrator to install or uninstall «Windows Media Player Legacy (App)».
N editions of Windows include the same functionality as other editions of Windows, except for media-related technologies, Windows Media Player, and certain preinstalled media apps (Groove, Movies & TV, Voice Recorder, and Skype). N editions will need to install the Media Feature Pack to restore these excluded technologies.
Contents
- Option One: Install or Uninstall «Windows Media Player Legacy (App)» in Settings
- Option Two: Install or Uninstall «Windows Media Player Legacy (App)» in Windows Features
- Option Three: Install or Uninstall «Windows Media Player Legacy (App)» using DISM Command
- Option Four: Install or Uninstall «Windows Media Player Legacy (App)» in PowerShell
EXAMPLE: Windows Media Player Legacy app
Option One
Install or Uninstall «Windows Media Player Legacy (App)» in Settings
1 Open Settings (Win+I).
2 Click/tap on System on the left side, and click/tap on Optional features on the right side. (see screenshot below)
3 Do step 4 (install) or step 5 (uninstall) below for what you want.
4 Install «Windows Media Player Legacy (App)»
A) Click/tap on the View features button. (see screenshot below)
B) Check Windows Media Player Legacy (App), and click/tap on Next. (see screenshot below)
C) Click/tap on Add to confirm. (see screenshot below)
D) When Windows Media Player Legacy (App) has finished being added, you can close Settings if you like. (see screenshot below)
5 Uninstall «Windows Media Player Legacy (App)»
A) Under Added features, click/tap on Windows Media Player Legacy (App) to expand it open, and click/tap on the Remove button. (see screenshot below)
B) When Windows Media Player Legacy (App) has finished being removed, you can close Settings if you like. (see screenshot below)
Option Two
Install or Uninstall «Windows Media Player Legacy (App)» in Windows Features
1 Open Windows Features (OptionalFeatures.exe).
2 Expand open Media Features. (see screenshot below step 3)
3 Check (install) and uncheck (uninstall) Windows Media Player Legacy (App) for what you want. (see screenshot below)
4 If you unchecked Windows Media Player Legacy (App), then click/tap on Yes to confirm. (see screenshot below)
5 Click/tap on OK. (see screenshot below)
6 Windows Media Player Legacy (App) will now be installed or uninstalled. Click/tap on Close. (see screenshot below)
Option Three
Install or Uninstall «Windows Media Player Legacy (App)» using DISM Command
1 Open Windows Terminal (Admin), and select either Windows PowerShell or Command Prompt.
2 Copy and paste the command below you want to use into Windows Terminal (Admin), and press Enter. (see screenshots below)
Install «Windows Media Player Legacy (App)»
DISM /Online /Enable-Feature /FeatureName:"WindowsMediaPlayer" /All
OR
Uninstall «Windows Media Player Legacy (App)»
DISM /Online /Disable-Feature /FeatureName:"WindowsMediaPlayer"
Option Four
Install or Uninstall «Windows Media Player Legacy (App)» in PowerShell
1 Open Windows Terminal (Admin), and select Windows PowerShell.
2 Copy and paste the command below you want to use into Windows Terminal (Admin), and press Enter. (see screenshots below)
Install «Windows Media Player Legacy (App)»
Enable-WindowsOptionalFeature -FeatureName "WindowsMediaPlayer" -All -Online
OR
Uninstall «Windows Media Player Legacy (App)»
Disable-WindowsOptionalFeature -FeatureName "WindowsMediaPlayer" -Online
That’s it,
Shawn Brink
Related Tutorials
- Add or Remove Optional Features in Windows 11
- Download and Install Media Feature Pack for Windows 11 N Editions
- Enable or Disable DLNA Media Streaming in Windows 10 and Windows 11