Saturday, April 12, 2025

Remotely plays a Star Wars quote with temporary volume and speech rate adjustments.

 How to use the improved script:

  1. Save the script as a .ps1 file (e.g., SpeakRemote.ps1).

  2. Run it from your local PowerShell with the -ComputerName parameter:

    PowerShell
    .\SpeakRemote.ps1 -ComputerName "YourRemoteComputerName" -Verbose
    

    Replace "YourRemoteComputerName" with the actual name of the remote computer. The -Verbose switch is optional but highly recommended for seeing the detailed output.

This improved script is more robust, easier to understand, and provides better feedback during execution.


<#

.SYNOPSIS

Remotely plays a Star Wars quote with temporary volume and speech rate adjustments.


.DESCRIPTION

This script connects to a remote computer, adjusts the system volume and speech rate,

speaks a predefined Star Wars quote, and then restores the original volume and

speech rate settings. It utilizes COM interop to control the audio endpoint

volume and the System. Speech namespace for text-to-speech functionality.


.PARAMETER ComputerName

The name of the remote computer to connect to.


.EXAMPLE

Enter-PSSession -ComputerName Server01

Start-Job -ScriptBlock { ... } # The script block below


.NOTES

Requires remote PowerShell connectivity to the target computer.

The script block is designed to be executed remotely within a PowerShell job.

#>

param(

    [Parameter(Mandatory=$true)]

    [string]$ComputerName

)


Enter-PSSession -ComputerName $ComputerName -ErrorAction Stop


try {

    Start-Job -ScriptBlock {

        #region COM Interop Definitions

        Add-Type -TypeDefinition @'

        using System.Runtime.InteropServices;


        [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

        interface IAudioEndpointVolume {

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

          }

        }

        '@

        #endregion


        #region Speech Synthesis Initialization

        Add-Type -AssemblyName System.Speech

        $Voice = New-Object System.Speech.Synthesis.SpeechSynthesizer

        #endregion


        #region Store Original Settings

        Write-Verbose "Getting current mute status..."

        $CurrentMute = [Audio]::Mute

        Write-Verbose "Current mute status: $CurrentMute"


        Write-Verbose "Getting current volume level..."

        $CurrentVol = [Audio]::Volume

        Write-Verbose "Current volume level: $($CurrentVol * 100)%"


        Write-Verbose "Getting current speech rate..."

        $CurrentRate = $Voice.Rate

        Write-Verbose "Current speech rate: $CurrentRate"

        #endregion


        #region Adjust Audio and Speech

        Write-Verbose "Unmuting audio..."

        [Audio]::Mute = $False


        if ($CurrentVol -lt 0.25) {

            Write-Verbose "Current volume is below 25%, setting volume to 75%..."

            [Audio]::Volume = 0.75

        } else {

            Write-Verbose "Current volume is at or above 25%, no volume adjustment needed for speech."

        }


        Write-Verbose "Setting speech rate to -2..."

        $Voice.Rate = -2


        Write-Verbose "Speaking the quote..."

        $Quote = @"

Did you ever hear the tragedy of Darth Plagueis The Wise?

I thought not. It’s not a story the Jedi would tell you.

It’s a Sith legend. Darth Plagueis was a Dark Lord of the Sith,

    so powerful and so wise he could use the Force to influence the midichlorians to create life…

He had such a knowledge of the dark side that he could even keep the ones he cared about from dying.

The dark side of the Force is a pathway to many abilities some consider to be unnatural.

He became so powerful… the only thing he was afraid of was losing his power, which eventually, of course, he did.

Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep.

Ironic. He could save others from death, but not himself.

"@

        $Voice.Speak($Quote)

        #endregion


        #region Restore Original Settings

        Write-Verbose "Restoring original speech rate: $CurrentRate"

        $Voice.Rate = $CurrentRate


        Write-Verbose "Restoring original volume level: $($CurrentVol * 100)%"

        [Audio]::Volume = $CurrentVol


        Write-Verbose "Restoring original mute status: $CurrentMute"

        [Audio]::Mute = $CurrentMute


        Write-Verbose "Disposing of the speech synthesizer object."

        $Voice.Dispose()

        #endregion

    } -Name "SpeakQuoteJob-$ComputerName"

}

finally {

    Write-Verbose "Exiting PSSession on $ComputerName"

    Exit-PSSession

}

No comments:

Post a Comment

PAM maturity