DSCResources/AudioVolume/AudioVolume.psm1
$LibsPath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Libs' Add-Type -Path (Join-Path $LibsPath '\CoreAudio\netstandard2.0\CoreAudio.dll') [CoreAudio.PROPERTYKEY] $script:PKEY_DEVICE_INTERFACE_FRIENDLY_NAME = [CoreAudio.PROPERTYKEY]::new([Guid]::new('026E516E-B814-414B-83CD-856D6FEF4822'), 2) [CoreAudio.PROPERTYKEY] $script:PKEY_DEVICE_FRIENDLY_NAME = [CoreAudio.PROPERTYKEY]::new([Guid]::new('A45C254E-DF1C-4EFD-8020-67D146A850E0'), 14) [CoreAudio.PROPERTYKEY] $script:PKEY_DEVICE_DESCRIPTION = [CoreAudio.PROPERTYKEY]::new([Guid]::new('A45C254E-DF1C-4EFD-8020-67D146A850E0'), 2) [CoreAudio.PROPERTYKEY] $script:PKEY_SYSTEM_NAME = [CoreAudio.PROPERTYKEY]::new([Guid]::new('B3F8FA53-0004-438E-9003-51A46E139BFC'), 6) function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $DeviceName, [Parameter(Mandatory = $true)] [ValidateRange(0, 100)] [uint16] $Volume ) $MMDevice = Get-MMDevice -DeviceName $DeviceName if ($null -eq $MMDevice) { Write-Verbose ('Device not found') return $null } $result = @{} $result.DeviceName = $MMDevice.Properties.Item($script:PKEY_DEVICE_FRIENDLY_NAME).Value $result.DeviceId = $MMDevice.ID $result.State = $MMDevice.State.ToString() $result.IsDefaultDevice = $MMDevice.Selected $result.Volume = [uint16]($MMDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100) $result.Mute = $MMDevice.AudioEndpointVolume.Mute return $result } function Test-TargetResource { [CmdletBinding()] [OutputType([bool])] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $DeviceName, [Parameter(Mandatory = $true)] [ValidateRange(0, 100)] [uint16] $Volume, [Parameter()] [bool] $Mute = $false, [Parameter()] [bool] $SkipWhenDeviceNotPresent = $false, [Parameter()] [string] $State, [Parameter()] [bool] $IsDefaultDevice, [Parameter()] [string] $DeviceId ) $CurrentState = Get-TargetResource -DeviceName $DeviceName -Volume $Volume if ($null -eq $CurrentState) { if ($SkipWhenDeviceNotPresent) { Write-Warning 'Device not found but TEST RETURNS TRUE because SkipWhenDeviceNotPresent is specified as true.' return $true } else { return $false } } Write-Verbose ('Device Found: {0}' -f $CurrentState.DeviceName) Write-Verbose ('Device ID: {0}' -f $CurrentState.DeviceId) Write-Verbose ('Current State: {0}' -f $CurrentState.State) Write-Verbose ('Current Volume: {0}' -f $CurrentState.Volume) Write-Verbose ('Current Mute: {0}' -f $CurrentState.Mute) if ($CurrentState.Mute -ne $Mute) { Write-Verbose ('Mute state is not desited one. Test failed.') return $false } if ($CurrentState.Volume -ne $Volume) { Write-Verbose ('Volume is not desited value. Test failed.') return $false } Write-Verbose 'All states are desired. Test passed.' return $true } function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $DeviceName, [Parameter(Mandatory = $true)] [ValidateRange(0, 100)] [uint16] $Volume, [Parameter()] [bool] $Mute = $false, [Parameter()] [bool] $SkipWhenDeviceNotPresent = $false, [Parameter()] [string] $State, [Parameter()] [bool] $IsDefaultDevice, [Parameter()] [string] $DeviceId ) $MMDevice = Get-MMDevice -DeviceName $DeviceName if ($null -eq $MMDevice) { Write-Verbose ('Device not found') if (-not $SkipWhenDeviceNotPresent) { Write-Error 'Device not found' return } } if ($MMDevice.State -ne [CoreAudio.DEVICE_STATE]::DEVICE_STATE_ACTIVE) { Write-Error ('We can not change volume when the device is not Active. (Current State is {0})' -f $MMDevice.State.ToString()) return } try { $MMDevice.AudioEndpointVolume.MasterVolumeLevelScalar = ($Volume / 100) Write-Verbose ('Changed the volume to {0}' -f [int]($MMDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100)) $MMDevice.AudioEndpointVolume.Mute = $Mute Write-Verbose ('Changed the mute states to {0}' -f $MMDevice.AudioEndpointVolume.Mute) } catch { Write-Error -Exception $_.Exception Write-Verbose 'Operation Failed.' return } Write-Verbose 'Operation Completed.' } function Get-MMDevice([string]$DeviceName) { $enum = [CoreAudio.MMDeviceEnumerator]::new() $allDevices = $enum.EnumerateAudioEndPoints([CoreAudio.EDataFlow]::eRender, ([CoreAudio.DEVICE_STATE]::DEVICE_STATE_ACTIVE -bor [CoreAudio.DEVICE_STATE]::DEVICE_STATE_UNPLUGGED -bor [CoreAudio.DEVICE_STATE]::DEVICE_STATE_DISABLED)) foreach ($device in $allDevices) { if ($device.Properties.Item($script:PKEY_DEVICE_FRIENDLY_NAME).Value -match $DeviceName) { return $device break } } return $null } Export-ModuleMember -function *-TargetResource |