How To Automatically Mute Sound When Headphones Are Unplugged On Windows 10

Windows 10 can keep separate audio profiles for different audio devices. For each audio device that you connect, you can set a different volume level and when the device is connected, the volume will adjust automatically. Of course, no one keeps an audio device muted all the time. They will increase or decrease the volume but no one habitually mutes an audio device. If you use a pair of headphones with your desktop, and often have to disconnect them, you can use a little PowerShell script that will automatically mute sound when you unplug your headphones.

This is something that mobile phones do i.e., when you unplug your headphones, the music stops automatically. The logic behind this is that you’re either done listening to music or you’ve accidentally removed your headphones and you need a quick way to turn it off. The script was basically written on that same principle by Prateek Singh of GEEKEEFY.

Automatically Mute Sound

Open Notepad and paste the following;

[cmdletbinding()]
Param()

#Adding definitions for accessing the Audio API
Add-Type -TypeDefinition @'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume {
// f(), g(), ... are unused COM method slots. Define these if you care
int f(); int g(); int h(); int i();
int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
int j();
int GetMasterVolumeLevelScalar(out float pfLevel);
int k(); int l(); int m(); int n();
int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice {
int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator {
int f(); // Unused
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }
public class Audio {
static IAudioEndpointVolume Vol() {
var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
IMMDevice dev = null;
Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
IAudioEndpointVolume epv = null;
var epvid = typeof(IAudioEndpointVolume).GUID;
Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
return epv;
}
public static float Volume {
get {float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v;}
set {Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty));}
}
public static bool Mute {
get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
}
}
'@ -Verbose


While($true)
{
#Clean all events in the current session since its in a infinite loop, to make a fresh start when loop begins
Get-Event | Remove-Event -ErrorAction SilentlyContinue

#Registering the Event and Waiting for event to be triggered
Register-WmiEvent -Class Win32_DeviceChangeEvent
Wait-Event -OutVariable Event |Out-Null

$EventType = $Event.sourceargs.newevent | `
Sort-Object TIME_CREATED -Descending | `
Select-Object EventType -ExpandProperty EventType -First 1

#Conditional logic to handle, When to Mute/unMute the machine using Audio API
If($EventType -eq 3) 
{
[Audio]::Mute = $true
Write-Verbose "Muted [$((Get-Date).tostring())]"
}
elseif($EventType -eq 2 -and [Audio]::Mute -eq $true)
{
[Audio]::Mute = $false
Write-Verbose "UnMuted [$((Get-Date).tostring())]"
}
}

Save it with the PS1 file extension. Make sure you select ‘All Files’ from the file type dropdown. Give the file a name that will tell you at a glance what it does. Save it some place you’re unlikely to delete it by accident but also where you can find it easily if you need to.

Running The Script

PowerShell can’t just autorun a script. There is a built-in security measure the prevents it from doing so but there’s a way around it. We have a detailed article on how you can do just that. Follow the instructions to auto-run the PowerShell script you just created, and use a scheduled task to start the script every time you boot your PC.

Alternatively, you can manually run the script when you boot your system. I’ve been using it for less than 30 minutes and I don’t know how I was living without it before.

Read How To Automatically Mute Sound When Headphones Are Unplugged On Windows 10 by Fatima Wahab on AddictiveTips – Tech tips to make you smarter

How To Disable Windows PowerShell 2.0 On Windows 10

The current version of Windows PowerShell is 5. PowerShell comes pre-installed in Windows 10  and has replaced Command Prompt in the Power user menu. While PowerShell 5 is the stable version running on your system, the PowerShell 2.0 engine is still enabled on it and this version of PowerShell is now recognized as a security risk that can be used to run malicious scripts. Windows 10 deprecated it in the Fall Creators Update however, that doesn’t mean that it’s been removed for all users. It may still be enabled on your system. Here’s how you can check if you’re still running this engine, and how you can disable Windows PowerShell 2.0.

Check PowerShell 2.0

Open PowerShell with administrative rights and run the following command.

Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2

In the results that this command returns, look at the State field. If it says that this engine is Enabled, then you need to disable it. If the State returns the Disabled value, you’re good to go. You do not need to do anything else.

Disable Windows PowerShell 2.0 Engine

Open PowerShell with administrative rights, and run the following command;

Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root

This will disable Windows PowerShell 2.0 engine. You can check it by running this command again. The State should return ‘Disabled’.

If you’re not comfortable running the command in PowerShell, you can disable the feature from the Control Panel as well. Open File Explorer and enter the following in the location bar.

Control Panel\Programs

Click ‘Turn Windows features on or off’. This will open a new window called ‘Windows Features’. It may take a little time for this window to load the list of features that you can enable/disable. Once the list loads, scroll to the end and look for Windows PowerShell 2.0. Uncheck it, and click OK. You do not need to restart your system for this to take affect.

What’s The Risk?

Windows PowerShell 5 has an anti-malware feature that scans and prevents malicious scripts from running however, the PowerShell 2.0 engine can be used to run a downgrade attack that can bypass the anti-malware check. This will ultimately result in a malicious PowerShell script running on your system.

Disabling the engine shouldn’t have any negative impacts. Microsoft is aware that some apps still use PowerShell 2.0 but they’re working to help migrate them to a newer version. While this feature has been deprecated, it will still remain a part of Windows 10 for the foreseeable future and users will be able to enable it if they need/want to.

Read How To Disable Windows PowerShell 2.0 On Windows 10 by Fatima Wahab on AddictiveTips – Tech tips to make you smarter