PowerShellを使ってシステムのマイクのミュート状態を確認する方法

PowerShellを使ってシステムのマイクのミュート状態を確認する方法という問いには、デバイス存在をCIMで確認し、標準機能だけならサウンド設定と会議アプリの入力表示で対象マイクのミュートを確認するという方法で答えます。Win32_SoundDeviceのStatusはデバイス状態でありミュート値ではない。Windows Core AudioのIAudioEndpointVolume::GetMuteがエンドポイントのミュートBOOLを返すが、標準PowerShellには全エンドポイント対応の汎用コマンドレットがない。この記事ではマイクのエンドポイントID、既定入力先、IAudioEndpointVolumeのMute値、会議アプリ内の状態を別々に記録するを判断軸にし、実行前の確認、記事固有のコード、合否判定、戻し方を一続きで示します。

音声デバイスの正常性ではなく、OSエンドポイントと会議アプリ双方のミュートを識別する。完了は「どの入力エンドポイントを確認したか明示し、OSエンドポイントとアプリ内ミュートの双方を区別して報告できる」と定義します。対象が取れない場合は「入力デバイスが0件なら接続、プライバシー権限、無効化、リモートセッションのリダイレクトを確認する」として切り分け、推測で成功扱いにしません。

目次

デバイス状態とエンドポイントMuteを分ける

デバイス存在をCIMで確認し、標準機能だけならサウンド設定と会議アプリの入力表示で対象マイクのミュートを確認する。マイクのミュート状態確認ではこの進め方により、操作したという事実ではなく、期待する状態へ到達したかでタイトルの問いへ答えられます。音声デバイスの正常性ではなく、OSエンドポイントと会議アプリ双方のミュートを識別する。

デバイス状態とエンドポイントMuteを分けるの合格条件は、どの入力エンドポイントを確認したか明示し、OSエンドポイントとアプリ内ミュートの双方を区別して報告できることです。作業時刻、実行ユーザー、端末名を添え、判断に使った値が後から追える形にします。

Win32_SoundDeviceで存在だけ確認

Win32_SoundDeviceで存在だけ確認では、マイクのミュート状態確認の対象を「マイクのエンドポイントID、既定入力先、IAudioEndpointVolumeのMute値、会議アプリ内の状態を別々に記録する」という単位で扱います。Win32_SoundDeviceのStatusはデバイス状態でありミュート値ではない。Windows Core AudioのIAudioEndpointVolume::GetMuteがエンドポイントのミュートBOOLを返すが、標準PowerShellには全エンドポイント対応の汎用コマンドレットがない。対象が複数なら表示名の部分一致で先頭を採らず、一意になる条件を追加します。

マイクのミュート状態確認を始める前に、PowerShellの版、コマンドの提供元、必要権限、管理ポリシーの有無を確認します。権限不足と対象なしは意味が異なるため、例外を0件へ置き換えません。

設定画面の入力メーターを開く

設定画面の入力メーターを開くは変更前の基準点です。マイクのエンドポイントID、既定入力先、IAudioEndpointVolumeのMute値、会議アプリ内の状態を別々に記録するを出力に含め、取得時刻と一緒に保存します。値だけを切り取ると別対象との比較になるため、識別列を省きません。

$soundDevices = @(Get-CimInstance Win32_SoundDevice -ErrorAction Stop)
$soundDevices | Select-Object Name, Status, Manufacturer, PNPDeviceID
if ($soundDevices.Count -eq 0) {
  throw '音声デバイスが0件です。接続、無効化、リモートリダイレクトを確認してください。'
}
# Status=OKはデバイス状態であり、ミュート解除を意味しない。

Win32_SoundDeviceのStatusはデバイス状態でありミュート値ではない。Windows Core AudioのIAudioEndpointVolume::GetMuteがエンドポイントのミュートBOOLを返すが、標準PowerShellには全エンドポイント対応の汎用コマンドレットがない。出力が多い場合も最初から無理に一件へ絞らず、候補数と除外理由を残してから対象を決めます。

GetMuteが返すBOOLの意味

GetMuteが返すBOOLの意味では、デバイス存在をCIMで確認し、標準機能だけならサウンド設定と会議アプリの入力表示で対象マイクのミュートを確認する。マイクのミュート状態確認の例中にある名前、パス、ID、時刻はサンプルなので、そのまま本番へ貼らず、直前の読み取り結果から承認値を入れます。

Add-Type -TypeDefinition @'
using System;
using System.Runtime.InteropServices;

namespace Ittrip.CoreAudio {
  [ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
  internal class MMDeviceEnumeratorComObject {}

  [ComImport, Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"),
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  internal interface IMMDeviceEnumerator {
    [PreserveSig] int EnumAudioEndpoints(int dataFlow, uint stateMask, out IntPtr devices);
    [PreserveSig] int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice device);
    [PreserveSig] int GetDevice([MarshalAs(UnmanagedType.LPWStr)] string id, out IMMDevice device);
    [PreserveSig] int RegisterEndpointNotificationCallback(IntPtr client);
    [PreserveSig] int UnregisterEndpointNotificationCallback(IntPtr client);
  }

  [ComImport, Guid("D666063F-1587-4E43-81F1-B948E807363F"),
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  internal interface IMMDevice {
    [PreserveSig] int Activate(ref Guid iid, int clsCtx, IntPtr activationParams,
      [MarshalAs(UnmanagedType.IUnknown)] out object interfacePointer);
    [PreserveSig] int OpenPropertyStore(int access, out IntPtr properties);
    [PreserveSig] int GetId([MarshalAs(UnmanagedType.LPWStr)] out string id);
    [PreserveSig] int GetState(out uint state);
  }

  [ComImport, Guid("5CDF2C82-841E-4546-9722-0CF74078229A"),
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  internal interface IAudioEndpointVolume {
    [PreserveSig] int RegisterControlChangeNotify(IntPtr notify);
    [PreserveSig] int UnregisterControlChangeNotify(IntPtr notify);
    [PreserveSig] int GetChannelCount(out uint channelCount);
    [PreserveSig] int SetMasterVolumeLevel(float levelDb, ref Guid eventContext);
    [PreserveSig] int SetMasterVolumeLevelScalar(float level, ref Guid eventContext);
    [PreserveSig] int GetMasterVolumeLevel(out float levelDb);
    [PreserveSig] int GetMasterVolumeLevelScalar(out float level);
    [PreserveSig] int SetChannelVolumeLevel(uint channel, float levelDb, ref Guid eventContext);
    [PreserveSig] int SetChannelVolumeLevelScalar(uint channel, float level, ref Guid eventContext);
    [PreserveSig] int GetChannelVolumeLevel(uint channel, out float levelDb);
    [PreserveSig] int GetChannelVolumeLevelScalar(uint channel, out float level);
    [PreserveSig] int SetMute([MarshalAs(UnmanagedType.Bool)] bool muted, ref Guid eventContext);
    [PreserveSig] int GetMute([MarshalAs(UnmanagedType.Bool)] out bool muted);
  }

  public sealed class EndpointMuteState {
    public int Role { get; set; }
    public string EndpointId { get; set; }
    public bool IsMuted { get; set; }
  }

  public static class MicrophoneMuteReader {
    public static EndpointMuteState ReadDefaultCapture(int role) {
      if (role < 0 || role > 2) throw new ArgumentOutOfRangeException("role");
      IMMDeviceEnumerator enumerator = null;
      IMMDevice device = null;
      object endpointObject = null;
      try {
        enumerator = (IMMDeviceEnumerator)new MMDeviceEnumeratorComObject();
        Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(1, role, out device));
        string endpointId;
        Marshal.ThrowExceptionForHR(device.GetId(out endpointId));
        Guid iid = typeof(IAudioEndpointVolume).GUID;
        Marshal.ThrowExceptionForHR(device.Activate(ref iid, 23, IntPtr.Zero, out endpointObject));
        IAudioEndpointVolume volume = (IAudioEndpointVolume)endpointObject;
        bool muted;
        Marshal.ThrowExceptionForHR(volume.GetMute(out muted));
        return new EndpointMuteState { Role = role, EndpointId = endpointId, IsMuted = muted };
      } finally {
        if (endpointObject != null && Marshal.IsComObject(endpointObject)) Marshal.ReleaseComObject(endpointObject);
        if (device != null && Marshal.IsComObject(device)) Marshal.ReleaseComObject(device);
        if (enumerator != null && Marshal.IsComObject(enumerator)) Marshal.ReleaseComObject(enumerator);
      }
    }
  }
}
'@

Win32_SoundDevice Status=OKを『ミュート解除』と誤解しない。確認記事で音量や既定先を変更しない。マイクのミュート状態確認でプレビュー対応コマンドを使える場合はWhatIfを先に実行し、非対応の操作は対象一覧と引数を画面へ出して人が承認してから一度だけ実行します。

標準PowerShellに汎用cmdletはない

標準PowerShellに汎用cmdletはないでは同じ対象を別経路でもう一度読みます。判定したいのは「コマンドが終了したか」ではなく、どの入力エンドポイントを確認したか明示し、OSエンドポイントとアプリ内ミュートの双方を区別して報告できるかどうかです。

$roleNames = @{ 0='Console'; 2='Communications' }
$muteStates = foreach ($role in @(0,2)) {
  $state = [Ittrip.CoreAudio.MicrophoneMuteReader]::ReadDefaultCapture($role)
  [pscustomobject]@{
    Role=$roleNames[$role]; EndpointId=$state.EndpointId
    IsMuted=$state.IsMuted; CheckedAt=Get-Date
  }
}
$muteStates | Format-Table Role, EndpointId, IsMuted, CheckedAt
if (@($muteStates).Count -ne 2) { throw '既定Captureエンドポイントを役割別に取得できません。' }
Start-Process 'ms-settings:sound'
# 会議アプリ内ミュートはこのOSエンドポイント値とは別に確認する。

入力デバイスが0件なら接続、プライバシー権限、無効化、リモートセッションのリダイレクトを確認する。マイクのミュート状態確認の期待値と実測値が一致しないときは追加変更を重ねず、対象識別、権限、ポリシー、時間差の順で原因を分けます。

会議アプリ独自ミュートを確認

Win32_SoundDevice Status=OKを『ミュート解除』と誤解しない。確認記事で音量や既定先を変更しない。会議アプリ独自ミュートを確認に該当したら、警告を消して継続するのではなく、どの条件で止まったかを記録します。

入力デバイスが0件なら接続、プライバシー権限、無効化、リモートセッションのリダイレクトを確認する。マイクのミュート状態確認ではエラー本文、FullyQualifiedErrorId、対象ID、直前に成功した段階を残すと、別担当者が安全な地点から調査できます。

複数マイクの既定先を特定

読み取りと画面確認のみ。誤って設定を変えた場合は控えた既定入力先とアプリ状態へ戻す。復旧操作にも同じ識別条件を使い、名前が似た別対象へ戻し処理を適用しません。

  • マイクのミュート状態確認の変更前値と取得時刻
  • 復旧対象: マイクのエンドポイントID、既定入力先、IAudioEndpointVolumeのMute値、会議アプリ内の状態を別々に記録する
  • 復旧後の判定: どの入力エンドポイントを確認したか明示し、OSエンドポイントとアプリ内ミュートの双方を区別して報告できる
  • 再実行を止める条件: Win32_SoundDevice Status=OKを『ミュート解除』と誤解しない。確認記事で音量や既定先を変更しない

確認結果を誤って変更しない

完全自動化するならCore Audio APIを正しくラップした組織承認済みツールを用意し、出所不明モジュールを導入しない。マイクのミュート状態確認を繰り返す場合は、正常、対象なし、要承認、失敗を異なる終了状態として記録し、前回値との比較だけで異常を決めません。

確認結果を誤って変更しないの識別軸マイクのエンドポイントID、既定入力先、IAudioEndpointVolumeのMute値、会議アプリ内の状態を別々に記録する
採用する実測どの入力エンドポイントを確認したか明示し、OSエンドポイントとアプリ内ミュートの双方を区別して報告できる
0件時の扱い入力デバイスが0件なら接続、プライバシー権限、無効化、リモートセッションのリダイレクトを確認する
保留にする兆候Win32_SoundDevice Status=OKを『ミュート解除』と誤解しない。確認記事で音量や既定先を変更しない

マイクのミュート状態確認の実行記録には、開始前の対象候補、採用した識別値、実行したコード、終了後の実測、除外した候補と理由を同じ作業番号で残します。特に「マイクのエンドポイントID、既定入力先、IAudioEndpointVolumeのMute値、会議アプリ内の状態を別々に記録する」を省くと、後日の再確認で別対象の値を比較するおそれがあります。画面コピーだけでなく、日時と端末名を含む構造化した出力も保存します。

PowerShellを使ってシステムのマイクのミュート状態を確認する方法を定期手順へ組み込む場合も、初回は対話的に候補を確認します。正常時は「どの入力エンドポイントを確認したか明示し、OSエンドポイントとアプリ内ミュートの双方を区別して報告できる」、判定不能時は「入力デバイスが0件なら接続、プライバシー権限、無効化、リモートセッションのリダイレクトを確認する」、中止時は「Win32_SoundDevice Status=OKを『ミュート解除』と誤解しない。確認記事で音量や既定先を変更しない」をそれぞれ別の結果として扱います。これにより、0件や例外を都合よく成功へ丸めず、次の担当者が同じ対象と条件で追試できます。

修正後コードの合格条件:Win32_SoundDeviceのStatusは存在確認にだけ使い、実際のミュートは既定CaptureエンドポイントをIAudioEndpointVolumeへActivateしてGetMuteで読みます。ConsoleとCommunicationsを別々に取得し、エンドポイントIDとBOOLを記録したうえでアプリ内ミュートは別判定にします。

公式情報・参考資料

マイクのミュート状態確認で使うコマンド名、引数、対応環境は次のMicrosoft一次資料で確認しました。記事の確認日は2026年7月17日です。OSやモジュール更新後は、実行端末のGet-Helpと併せて再確認してください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次