Many schools are gearing up for standardized testing season. A common setup is to use a custom user interface with a mandatory profile as this simplifies the entire process. Labs either automatically login (if reserved for testing) or students use a generic username/password. This setup works great unless something actually needs to be changed – like unmuting the audio or adjusting the volume.
We ran into this exact problem during a recent practice run. My first instinct was to start with PowerShell. I searched the cmdlets for volume and saw a very promising cmdlet named Set-Volume. Unfortunately, that cmdlet has nothing to do with sound as it is part of the storage module. Fortunately, I didn’t first try unmuting a computer by running no-volume. That could have been bad. 🙂
My second instinct was the internet. The PowerShell script below will unmute the computer and raise the audio to 90%. This script is linked as a PowerShell logon script for our users when testing. When the user first logs in, it will adjust the audio. It will continue to loop every 30 seconds. The script will end after 15 minutes of looping. Because headphones and speakers will have different audio settings, the loop ensures that the audio is adjusted if a user plugs in a different audio device during the test.
[int]$Loop = 1 while ($Loop -eq 30){ 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)); } } } '@ [ audio ]::Mute = $false [ audio ]::Volume = 0.9 $loop = $loop + 1 sleep -Seconds 30
The two [ audio ] lines at the end of the script determine the mute and volume percentage status. For example, you can change the 0.9 value to 0.5 to set the volume to 50%. 1.0 will set the volume at 100%. 5.4 will blow your speakers and make everything sound Darth Vadery. There you have it – a fairly simple way for setting sound volume and unmuting with PowerShell. Now on to my next project – preventing people from plugging headphones into microphone jacks. 🙂
The vast majority of this script was originally posted here.
Thanks Joseph! This is awesome.
Not a problem! 🙂
Your blog is awesome, you are really deploying hapiness, at least for me…
Thanks for the comment, Javier!
Dear Joseph,
Thank you for sharing the script.
I have run your script, it change the volume of the speaker.
can you show me how to change the volume of the Microphone ?
Thanks in Advance.
Regards Dat.
I second that!
Looking for a solution that would automatically un-mute the Mic and set an initial level.