How to use the improved script:
-
Save the script as a
.ps1
file (e.g.,SpeakRemote.ps1
). -
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