I hate it when someone calls and says they can’t hear their video while on a terminal server. 99% of the time is because the sound is muted on the local computer. Believe it or not, this is very simple to solve. We do this by using wscript.shell.

$Obj = New-Object -com wscript.shell

We first start by making the object wscript.shell. This little guy will give us all kinds of awesome access to a computer. Later we will wrap this up in an invoke-command.

1..100 | foreach-object { $obj.sendkeys([char]174) }

Next, we lower the volume to 0. We do this to have an absolute value. The char key 174 on the average windows computer is volume down. Thus we do it 100 times. Now we have an absolute, we can set the volume to what we want by increasing the value.

0..$Volume | foreach-object { $obj.sendkeys([char]175) }

This part will loop the volume up until the volume we tell it is reached. Using this method, we don’t have to create a sound object. We are using what is in the computer’s OS already.

The Script

function Set-SHDComputerSpeaker {
    [cmdletbinding()]
    param (
        [Parameter(
            ValueFromPipeline = $True,
            ValueFromPipelineByPropertyName = $True,
            HelpMessage = "Provide the target hostname",
            Mandatory = $true)][Alias('Hostname', 'cn')][String[]]$Computername,
        [Parameter(HelpMessage = "Allows for custom Credential.")][System.Management.Automation.PSCredential]$Credential,
        [Parameter(Helpmessage = "Increase volume by",Mandatory = $true)][int]$Volume
    )
    foreach ($computer in $Computername) {
        if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
            try {
                if ($PSBoundParameters.ContainsKey('Credential')) {
                    Invoke-Command -ComputerName $computer -Credential $Credential {
                        $Obj = New-Object -com wscript.shell
                        1..100 | foreach-object { $obj.sendkeys([char]174) }
                        0..$Volume | foreach-object { $obj.sendkeys([char]175) }
                    }
                }
                else {
                    Invoke-Command -ComputerName $computer {
                        $Obj = New-Object -com wscript.shell
                        1..100 | foreach-object { $obj.sendkeys([char]174) }
                        0..$Volume | foreach-object { $obj.sendkeys([char]175) }
                    }
                }
            }
            catch {
                Write-Warning "Unable to capture Data from $Computer."
            }
        }
        else {
            Write-Warning "$Computer is offline."
        }
    }
}

As stated above, we wrapped up the code into an invoke-command and placed some testing around it. Now all you have to do is:

Set-SHDComputerSpeaker -Computername 'Workstation1','Workstation2' -Volume 50

Or you can add the credential’s tag.

Set-SHDComputerSpeaker -Computername 'Worktation1',"Workstation2' -Volume 50 -Credential (Get-Credential)

I hope this is helpful to you. Share it with others if you find this useful.