How can I use powershell to set the speaker volume? Ive dug around on here and elsewhere online can cant really find an answer.

I think I will have to write something in C# that wraps a Win32 API and THEN call it from my powershell script. The Win32 API's would be one of these

[DllImport("winmm.dll")]
public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);

[DllImport("winmm.dll")]
public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
up vote 14 down vote accepted

SendKeys stopped working for me in Windows 10 (it literally types digits where my caret is). I found this blog post with a very convenient way of doing it.

First, run this to get access to 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)); }
    }
}
'@

Then control the volume like this:

[audio]::Volume  = 0.2 # 0.2 = 20%, etc.

And mute/unmute like this:

[audio]::Mute = $true  # Set to $false to un-mute

I created a cmdlet for manipulating audio devices.

http://www.automatedops.com/projects/windowsaudiodevice-powershell-cmdlet/

It even includes a live peak value display.

enter image description here

We can Mute, Volume Down, Volume Up speaker levels with these commands. A simple 1..50 loop (each counter = 2% volume) can be added to make a function that accepts input and adjusts volume without any need for C#.

Volume Mute

$obj = new-object -com wscript.shell
$obj.SendKeys([char]173)

Volume Down Button

$obj = new-object -com wscript.shell
$obj.SendKeys([char]174)

Volume Up Button

$obj = new-object -com wscript.shell
$obj.SendKeys([char]175)

Find some relevant info here.

How can I mute/unmute my sound from PowerShell

http://blogs.technet.com/b/heyscriptingguy/archive/2013/07/28/weekend-scripter-cheesy-script-to-set-speaker-volume.aspx

EDIT: Here is a reusable function, tested and working on W7x64 w/ Powershell v2.

Function Set-Speaker($Volume){$wshShell = new-object -com wscript.shell;1..50 | % {$wshShell.SendKeys([char]174)};1..$Volume | % {$wshShell.SendKeys([char]175)}}
#

Example usage. Remember each tick is 2%

#Sets volume to 60%
Set-Speaker -Volume 30

#Sets volume to 80%
Set-Speaker -Volume 40

#Sets volume to 100%
Set-Speaker -Volume 50

and this function will Toggle-Mute

Function Toggle-Mute(){$wshShell = new-object -com wscript.shell;$wshShell.SendKeys([char]173)}
#

Check out this PC Volume Control script on TechNet. It claims to do what you're asking for - well at least on Windows XP. Here's another approach that uses a tool called NirCmd.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.