PMPの流儀

PMPの流儀

エンジニアのページ

MENU

Windows10 標準機能で、ログイン時に音量を下げる方法 (PowerShell)

ログイン時にPCの音量を自動的に下げる方法を紹介します。ツールなどは不要でWindows10の素の状態のままできるのでインストールが禁止されている会社のPCでも安心です。
大きな音がして驚かれた経験がある方はどうぞ
f:id:ruruucky:20210223012308p:plain

 

1. 概要

PowerShellを使って音量を変更するスクリプトを用意し、それをタスクスケジューラからログイン時に呼び出すことで実現します。

2. スクリプト準備

2.1 AudioVolume.ps1

以下のスクリプトをメモ帳に貼り付けて、AudioVolume.ps1 という名前で保存してください。

# Audio Volume Setting Script for Windows10
#
# usage:
#   AudioVolume.ps1 Volume [0-100]
#   AudioVolume.ps1 Mute [On|Off]
#
# sample
#   AudioVolume.ps1 Volume 20
#   AudioVolume.ps1 Mute On
#   AudioVolume.ps1 Mute Off

param([string]$type, $val)

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)); }
    }
}
'@

switch($type) {
    'Volume' {
        [int]$vol = $val;
        if( ($vol -ge 0) -and ($vol -le 100) ) {
            [Audio]::Volume = ([float]$vol) / 100;
        }
    }

    'Mute' {
        switch($val) {
            'On' { [Audio]::Mute = $true; }
            'Off' { [Audio]::Mute = $false; }
        }
    }
}

2.2 launch_ps.js

以下のサイトから、launch_ps.js の内容をメモ帳に貼り付けて保存してください。
pmp-style.hatenablog.com

AudioVolume.ps1と launch_ps.js のファイルは同じフォルダに入れてください。この記事では c:\temp で説明します。

3. タスクスケジューラに登録

  1. スタートボタンで右クリックしてメニューを出して、「コンピュータの管理」を選択します。
  2. 「タスクスケジューラ」を押した後、「基本タスクの作成」を押します。 f:id:ruruucky:20210223005135p:plain

  3. 名前欄に「起動時音量設定」を入力します。(名前は何でも大丈夫す) その後、「次へ」をクリック f:id:ruruucky:20210223005302p:plain

  4. 「ログオン時」を選択して、「次へ」をクリック f:id:ruruucky:20210223005423p:plain

  5. 「次へ」をクリック f:id:ruruucky:20210223005511p:plain

  6. コマンドの設定をおこないます。 f:id:ruruucky:20210223005611p:plain

「プログラム/スクリプトwscript.exe を記入します。
「引数の追加(オプション)」に以下を記入します。15の部分がボリュームです。0~100の間で指定できます。

lanunch_ps.js AudioVolume.ps1 Volume 15

※参考 音量の設定ではなく、ミュートさせることも可能です。その場合は以下を入力します。

lanunch_ps.js AudioVolume.ps1 Mute On

「場所(オプション)」には、C:\temp (スクリプトを置いたフォルダ)を入力します。

完了したら「次へ」をクリック

  1. 内容を確認したら、「完了」をクリック f:id:ruruucky:20210223005903p:plain

4. 動作確認

事前に設定値とは違う音量に変えておきます。

タスクスケジューラから登録したスクリプト上で右クリックしてメニューから「実行」を選んでください。
f:id:ruruucky:20210223010507p:plain

これで音量が下がればOKです。

再度音量を変えて、ログインしなおしてみて、音量が変われば完成です。

5. 技術的解説

PowerShellには音量設定機能は無く、最大の難関でしたが、海外のサイトに凄い方がいて力業で実現していました。PowerShell内から埋め込みC#機能を使用して、音量用のCOMインターフェースを呼び出しています。.Net FrameworkWindowsの全ての機能が搭載されているわけではないので、C#からWin32 APIやCOMを呼び出すことはありますが、PowerShellからの呼び出しは初めて見ました。これが出来るなら万能ですわ~。
https://stackoverflow.com/questions/255419/how-can-i-mute-unmute-my-sound-from-powershell/19348221#19348221

タスクスケジューラからみると、以下の言語を経由しながら 音量用のCOMにアクセスしています。

JScriptPowerShellC# → COM

毎度ながら遠いです。

Windows10 の標準機能だけで実現しなくていいなら、VCで専用のコマンドを作ればどんなに楽な事か・・・。