Monday, August 17, 2020

Set-WinRMCert Script to easily set the Certificate for remote PowerShell

 I had to figure out from articles on the web how to set up Remote PowerShell to use SS:/HTTP

It was a PITA. 

I came up with this script recently to automate the task. 

It assumes that you already have a certificate loaded on the computer in the usual location that we put out computer certs.   "Cert:\LocalMachine\My"  If you put your cert in some different spot in the CERT: store, you will need to adjust this path. 

One important thing is that when you want to remote to a computer over SSL/https  you must connect with the FQDN.   So no shortcut, you need to do something like:

  • ' Enter-PSSession -UseSSL -ComputerName  Server01.famricam.com '

Running this script is only needed to be done once.  Assuming you get a success. 
Until your certificate expires. then you will need to re-run it. 

Here is the script. 

Set-WinRMCert.ps1

<#  
    .NOTES
    ===========================================================================
     Created with:  SAPIEN Technologies, Inc., PowerShell Studio 2020 v5.7.179
     Created on:    8/13/2020 10:15 AM
     Created by:    Richard Stoddart
     Filename:      Set-WinRMCert.ps1
    ===========================================================================
    .DESCRIPTION
        Enables Remote PS (WinRM) SSL HTTPS service.
        Sets certificate to default WinRM  port. Port 5986
#>

#Requires -RunAsAdministrator
#enable WinRM HTTPS service
& winrm quickconfig -transport:https -q
Start-Sleep -Seconds 2

#get Certificate
$CertPath = "Cert:\LocalMachine\My"
$cert = ((Get-ChildItem $CertPath | Sort-Object NotAfter )[-1] )
if (!$cert) { Write-error "Certificate not found in $CertPath "; return }

# Create text for CMD file
'CSCRIPT ' +
$env:SystemRoot +
'\System32\winrm.vbs ' + 
'set winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname="'+
$Cert.FriendlyName + 
'";CertificateThumbprint="' + 
$cert.Thumbprint +
'"}' |
Out-File -FilePath .\TempSetWinRM.cmd -Encoding oem

# Add below line Will turn off the HTTP WinRM port if not controled by GPO
# + "`n" +'winrm set winrm/config/Listener?Address=*+Transport=HTTP @{Enabled="false"}'

# Execute TempSetWinRM.CMD file
$Out = & .\TempSetWinRM.cmd

#vailidate config worked, catch error
$CertInstalled =
    (($out | ? { $_.trim() -like "CertificateThumbprint*" }).split("=")[1]).trim()

If ($CertInstalled -eq $cert.Thumbprint)
    { Write-Output "Sucess: Certificate $($cert.Thumbprint) $($Cert.Subject)" }
Else { Write-Error $out[0];  return}
Write-Output "`n"

#Output WinRM settings
Write-Output "Winrm Setting results `n --------------------------"

& Winrm enumerate winrm/config/listener

Remove-Item -Path '.\TempSetWinRM.cmd'

#GI WSMan:\localhost\Service\CertificateThumbprint | Set-Item -Value ""



END

Tuesday, March 3, 2020

Updating Powershell

My work laptop got refreshed / re-imaged.

I put a script together for my friends to update the help files and the Functions in PowerShell V5


We have a proxy server so we need to tell PowerShell to use that.
This works as a script, but not well from paste to command line.
and it will pop up some errors, when It can't find updates for some things.
The error output is acceptable to me.

Update-Powershell.PS1
#Requires -Version 5
#Requires -RunAsAdministrator
Start-Transcript Update-Powershell.txt

#Proxy
$wc = New-Object Net.WebClient
$wc.UseDefaultCredentials = $true
$wc.Proxy.Credentials = $wc.Credentials

#enable TLS*
if ([Net.ServicePointManager]::SecurityProtocol -ne ([Net.SecurityProtocolType].GetEnumNames() | ? { $_ -like "Tls*" }))
{ [Net.ServicePointManager]::SecurityProtocol = ([Net.SecurityProtocolType].GetEnumNames() | ? { $_ -like "Tls*" }) }

#Update Help Files
Update-Help -Force -ErrorAction Continue


#Fix the Repositiory defaults 
Register-PSRepository -Default
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted


Install-Module PowershellGet -Force
Install-PackageProvider -Name NuGet -Force

# Update modules

Get-Module -ListAvailable -verbose | Update-Module -verbose

# Import-Module
#Find-Module -Name PSWriteHTML | Install-Module
Install-Module -Name Az -AllowClobber -Scope AllUsers

Stop-Transcript

notepad Update-Powershell.txt

Please comment if you find this useful or could make improvements / additions. 

Tuesday, September 24, 2019

Automating Windows GUI with PowerShell

Automating Windows GUI with PowerShell - YouTube
https://youtu.be/MidlLSVp-m8

A script that demonstrates the capability to interact with the GUI in windows. There is info on my blog site about some of the code.


Just posted. I have been working on this demo since before the 2019 PowerShell Summit.
I hope you find it informative.

Please Follow / Subscribe to my channel, It will encourage me to do more.

Function
<#
.SYNOPSIS
Send a sequence of keys to an application window

.DESCRIPTION
This Send-Keys script send a sequence of keys to an application window.
To have more information about the key representation look at http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
(C)2013 Massimo A. Santin - Use it at your own risk.

.Source 
https://invista.wordpress.com/2013/08/16/a-simple-powershell-script-to-send-keys-to-an-application-windows/

.PARAMETER ApplicationTitle
The title of the application window

.PARAMETER Keys
The sequence of keys to send

.PARAMETER WaitTime
An optional number of seconds to wait after the sending of the keys

.EXAMPLE
Send-Keys "foobar - Notepad" "Hello world"

Send the sequence of keys "Hello world" to the application titled "foobar - Notepad".

.EXAMPLE
Send-Keys "foobar - Notepad" "Hello world" -WaitTime 5

Send the sequence of keys "Hello world" to the application titled "foobar - Notepad" 
and wait 5 seconds.

.EXAMPLE 
    New-Item foobar.txt -ItemType File; notepad foobar.txt ; Send-Keys "foobar - Notepad" "Hello world{ENTER}Ciao mondo{ENTER}" -WaitTime 1; Send-Keys "foobar - Notepad" "^s"

This command sequence creates a new text file called foobar.txt, opens the file using a notepad,
writes some text and saves the file using notepad.

.LINK
http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
#>
Function Send-Keys {
param (
    [Parameter(Mandatory=$True,Position=1)]
    [string]
    $ApplicationTitle,

    [Parameter(Mandatory=$True,Position=2)]
    [string]
    $Keys,

    [Parameter(Mandatory=$false)]
    [int] $WaitTime
    )

# load assembly cotaining class System.Windows.Forms.SendKeys
[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
#Add-Type -AssemblyName System.Windows.Forms

# add a C# class to access the WIN32 API SetForegroundWindow
Add-Type @"
    using System;
    using System.Runtime.InteropServices;
    public class StartActivateProgramClass {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
    }
"@

# get the applications with the specified title
$p = Get-Process | Where-Object { $_.MainWindowTitle -eq $ApplicationTitle }
if ($p) 
{
    # get the window handle of the first application
    $h = $p[0].MainWindowHandle
    # set the application to foreground
    [void] [StartActivateProgramClass]::SetForegroundWindow($h)

    # send the keys sequence
    # more info on MSDN at http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
    [System.Windows.Forms.SendKeys]::SendWait($Keys)
    if ($WaitTime) 
    {
        Start-Sleep -Seconds $WaitTime
    }
}
}


Demo Script
# Demo script
clear
#Includes
. "$PSScriptRoot\Send-Keys.ps1"

$SR = "C:\Scripts\Class\Summit_2019"
#$PSScriptRoot 

cls
Add-Type -AssemblyName System.speech
$tts = New-Object System.Speech.Synthesis.SpeechSynthesizer
# $tts.GetInstalledVoices().VoiceInfo
$tts.SelectVoice("Microsoft David Desktop") 
$tts.SelectVoice("Microsoft Zira Desktop") 


$tts.rate = 2

Write-Host   -ForegroundColor DarkGreen -BackgroundColor White "Powershell Presentaiton Demo"
#


 $Say = @("Good afternoon, 
I will be presentation on WhipItUpItTude. 
Our how I wrote a script to take control of the browser in logging into azure. 
`n
I created a script with a touch of anime flavor to help with this presentation.
 ")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)


 $Say = @("You ready Zira?" )
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)
 

# Start PPT

Write-Host   -ForegroundColor Gray "loading Part 0 `n "

& "C:\Program Files (x86)\Microsoft Office\root\Office16\POWERPNT.EXE" /s "$SR\eyes.pptx"

# wait for window to open. 
$Loop = 100
While ($Loop -gt 1)
{
    If (((Get-Process | ? { $_.mainwindowtitle -like "PowerPoint Slide Show  -  eyes.pptx"  }).mainwindowtitle)) { $loop = 0 }
    else { $loop-- }
    if ($loop -eq 1) { Return "timeout opening PowerPoint slide" }
    Write-Host "." -NoNewline
    Start-Sleep -Milliseconds 200
}
"`nPowerPoint Slide Show  -  eyes.pptx  login open, Proceed "

# Kick off voice


 Start-sleep -Seconds 3 
 $tts.SelectVoice("Microsoft Zira Desktop") 

 $Reply = $tts.SpeakAsync("Of Course I am, I’ve been waiting 3 ~thousand~ milliseconds. ") 

 Write-Host   -ForegroundColor Yellow "Zyra> Of course..."

  $Say = @("Well lets show the membership what we did")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

 Start-sleep -Seconds 8


 $Reply = $tts.SpeakAsync("Ok, since your standing there, lets do that. ") 
 Write-Host   -ForegroundColor Yellow "Zyra> OK, Since your standing there, lets do that."
 
 Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  eyes.pptx" -Keys "`r"
 Start-sleep -Seconds 1
 Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  eyes.pptx" -Keys "`r"
 Start-sleep -Seconds 1
 Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  eyes.pptx" -Keys "`r"
#Write part 1 complete

#wait for ppt to close.
    Write-Host "wait ." -NoNewline

$Loop = 100
While ($Loop -gt 1)
{
    If (((Get-Process | ? { $_.mainwindowtitle -like "PowerPoint Slide Show  -  eyes.pptx"  }).mainwindowtitle)) { $loop -- }
    else { $loop = 0  }
    if ($loop -eq 1) { return "Timeout closing PowerPoint slide show" }
    Write-Host "." -NoNewline -ForegroundColor Green
    Start-Sleep -Milliseconds 200
}


#intro
 $Say = @(
"`n`nI had the recurring irritant, that when I wanted to access my Azure Dashboard, 
  I had to go through 2 logins, and that is because I was using Chrome browser, 
 
  as it worked best in my environment....  and a proxy server login...
   it took a few steps and because of proxy server required yet another login. 
  SOmthing not required on IE/Edge")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)



#Show azure page. 

& "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "file://$SR\Azure-login.JPG"

Start-sleep -Seconds 25

Write-Host   -ForegroundColor Yellow "Zyra> I can help with that. It would be ideal to script it."
 $Reply = $tts.SpeakAsync("I can help with that. It would be ideal to script it.") 

 $Say = @(
"yea, But powershell is powershell not windows. 
 Maybe there is a way to send keystrokes to the open window and control it that way. 
 but I need to figure out how to write a script to acomplish that.")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

Start-sleep -Seconds 15

$tts.SelectVoice("Microsoft Zira Desktop")
 $Reply = $tts.SpeakAsync("So do some research.") 
Write-Host   -ForegroundColor Yellow "Zyra> So do some research.."


 $Say = @(
 "Thats called Whip It up a tude,  
 Sitting down and trying things and figuing out and trying different ways to do things in scripting. 
 Once you have a requirment you can figure out what to do. ")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)


  $Say = @(
 "... so I searched the internet to find a solution. ")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

 Start-sleep -Seconds 15
 $tts.SelectVoice("Microsoft Zira Desktop")
 $Reply = $tts.SpeakAsync("You mean Google searched the internet...") 
  Write-Host   -ForegroundColor Yellow "Zyra>You mean Google searched the internet..."
 
 
  $Say = @(
"well, yea, Google knows everything. The trick is asking the right questions.")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

Start-sleep -Seconds 8
  $Say = @("Soooo this is what I eventualy found, Zyra?")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)



#SHOW LOOKUP PAGE. 
& "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "$SR\Sendkeys.html"
Start-sleep -Seconds 15
$tts.SelectVoice("Microsoft David Desktop") 
 $Reply = $tts.SpeakAsync("Thanks to Massimo Santin, and sharing this on his blog.") 
 Write-Host   -ForegroundColor Cyan "David> Thanks to Massimo Santin, and sharing this on his blog."

 $Say = @(
 "I looked through this and copied it into ISE 
 The code has been available for a while and It looked great for what I needed
 Zyra, would you open it in ISE for me?")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)


$tts.SelectVoice("Microsoft Zira Desktop") 

Send-Keys -ApplicationTitle "A simple PowerShell script to send keys to an application windows | In Vista - Google Chrome" -Keys "{PGDN}"
Start-sleep -Seconds 3
Send-Keys -ApplicationTitle "A simple PowerShell script to send keys to an application windows | In Vista - Google Chrome" -Keys "{PGDN}"
Start-sleep -Seconds 4
Send-Keys -ApplicationTitle "A simple PowerShell script to send keys to an application windows | In Vista - Google Chrome" -Keys "{HOME}"
Start-sleep -Seconds 13



Start-sleep -Seconds 3
$Reply = $tts.SpeakAsync("Opening in Windows PowerShell I S E") 
 Write-Host   -ForegroundColor Yellow "Zyra>Opening in Windows PowerShell I S E"

#Open Powershell editor 

& "C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe" "$SR\Send-Keys.ps1 "

#Stop Chrome
#get-process Chrome |Stop-Process


# wait for window to open. 
$Loop = 100
While ($Loop -gt 1)
{
    If (((Get-Process | ? { $_.mainwindowtitle -like "Windows PowerShell ISE"  }).mainwindowtitle)) { $loop = 0 }
    else { $loop-- }
    if ($loop -eq 1) { Return "Timeout Windows PowerShell ISE" }
    Write-Host "." -NoNewline
    Start-Sleep -Milliseconds 200
}
"`nISE open, Proceed "


Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^1"

 $Say = @(
" I use it as function, So I could load it and have it available for script to use. ")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

Start-sleep -Seconds 10

$tts.SelectVoice("Microsoft David Desktop") 
 $Reply = $tts.SpeakAsync("Loading function.") 
 Write-Host   -ForegroundColor Cyan "David> Running script."

#Run Script in ISE
Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "{F5}"

Start-sleep -Seconds 4

 $Say = @(
"This creates a function, and obviouslyl provides no output.")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)


 $Say = @(
"NOW Lets open a window notepad and test it. 
Zira would you open it for me?")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)


Start-sleep -Seconds 4

$tts.SelectVoice("Microsoft Zira Desktop") 
 $Reply = $tts.SpeakAsync("Opening Notepad.") 
Write-Host   -ForegroundColor Yellow "Zyra> Opening Notepad"



#open notpad window
& Notepad.exe
 
Start-sleep -Seconds 8

## Demo geting the info about a window. 

#Send to  ISE
Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^i"

#conole window
Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^d CLS `r"

#script window
Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^i"
#new tab
Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^n"

 $Say = @(
"lets find the windows title of this notepad session")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "{(}get-process notepad*{)}.MainWindowTitle"
Start-sleep -Seconds 3


#Run Script in ISE
$tts.SelectVoice("Microsoft Zira Desktop")
$Reply = $tts.SpeakAsync("Running script.") 
Write-Host   -ForegroundColor Cyan "David> Running script."

Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "{F5}"

#Read-Host "PRESS ENTER" 

#new Page
Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^n"
 $Say = @(
"We found the window title of notepad with this")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

Start-sleep -Seconds 3

 $Say = @(
"Now lets see if we can send to the applicaion window
We can now use the function to send text to the window")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)


Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^d CLS `r"

#script window
Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^i"


#demo finding the window

Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "{(}get-process notepad*{)}.MainWindowTitle"
Start-sleep -Seconds 3
Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "{HOME} Send-Keys -ApplicationTitle {(} {END} {)} -Keys `" This is a test message `" "

 $Say = @(
"ok that should do the trick I added the code to find the title of the applicaion and pass it to the Notepad window")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

Start-sleep -Seconds 3
#Run Script in ISE
$tts.SelectVoice("Microsoft Zira Desktop")
 $Reply = $tts.SpeakAsync("Running script.") 

 Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "{F5}"
 
 Start-sleep -Seconds 10
$tts.SelectVoice("Microsoft Zira Desktop") 
 $Reply = $tts.SpeakAsync("You sent text to notepad, whoopie. what is the big deal?") 
 Write-Host   -ForegroundColor Yellow "Zyra>You sent text to notepad, whoopie. what is the big deal?"

 $Say = @(
 "Well it is a big deal, because I can send text to any window, and that includes a web browser. 
 And conveniently Chrome lables all the windows it has viewable, that we can address them. 
 And that is the basis of much more capablity. ")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

 Start-sleep -Seconds 15
$tts.SelectVoice("Microsoft Zira Desktop") 
 $Reply = $tts.SpeakAsync("Now what?") 
 Write-Host   -ForegroundColor Yellow "Zyra> Now what?"
# Stop Notepad
get-process notepad |Stop-Process

 $Say = @(
 "I worked out what the window titles were for Chrome. and how to open chrome brower up. 
 Assembled the code to identify the windows, and what text to send.
 Also added some code to handle the Login name, and the password for the firewall securely. 
  ")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

& "C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe" "$SR\start-azure.ps1"

 Start-sleep -Seconds 15
$tts.SelectVoice("Microsoft Zira Desktop") 
 $Reply = $tts.SpeakAsync("OPening start azure Script") 
 Write-Host   -ForegroundColor Yellow "Zyra> Now what?"
 Start-sleep -Seconds 1

Send-Keys -ApplicationTitle "Windows PowerShell ISE" -Keys "^3"
 #Read-Host "press enter to continue"

 $Say = @(
 "Running the result will not work with out internet connectivity, But I did record a presenation of the 
 operation: ")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)


 # Run powerpoint demo
& "C:\Program Files (x86)\Microsoft Office\root\Office16\POWERPNT.EXE" /s "$SR\Azure_start.pptx"


# wait for window to open. 

$Loop = 100
While ($Loop -gt 1)
{
    If (((Get-Process | ? { $_.mainwindowtitle -like "PowerPoint Slide Show  -  Azure_start.pptx"  }).mainwindowtitle)) { $loop = 0 }
    else { $loop-- }
    if ($loop -eq 1) { Return "timeout opening PowerPoint slide" }
    Write-Host "." -NoNewline
    Start-Sleep -Milliseconds 200
}
"`nPowerPoint Slide Show  -  Azure_start.pptx  login open, Proceed "
##############################
 Start-sleep -Seconds 4
 $tts.SelectVoice("Microsoft Zira Desktop") 
 $Reply = $tts.Speak("this is the shortcut that opens the powershell script") 
 Write-Host   -ForegroundColor Yellow "Zyra> Now what?"
 Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  Azure_start.pptx" -Keys "`r"
 Start-sleep -Seconds 4
 $Reply = $tts.Speak("opening Chrome browser to AZURE Portal website") 

 Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  Azure_start.pptx" -Keys "`r"
 Start-sleep -Seconds 1
 $Reply = $tts.Speak("Entering email") 
 Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  Azure_start.pptx" -Keys "`r"
 Start-sleep -Seconds 3
 Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  Azure_start.pptx" -Keys "`r"
 Start-sleep -Seconds 3
 Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  Azure_start.pptx" -Keys "`r"
 Start-sleep -Seconds 10


  Send-Keys -ApplicationTitle "PowerPoint Slide Show  -  Azure_start.pptx" -Keys "`r"
 Start-sleep -Seconds 3

start-sleep -Seconds 20

 $tts.SelectVoice("Microsoft David Desktop") 

  $Reply = $tts.SpeakAsync( "WELL THATS is our quick demo. ")
   Write-Host   -ForegroundColor Cyan "David> You know I could have read that for you. better probably."


  $Say = @(
 "Well, humans like to see each other, fumble with tech on stage.")
$tts.SelectVoice("Microsoft David Desktop") 
Write-Host   -ForegroundColor Cyan $Say
$tts.SpeakAsync($Say)

start-sleep -Seconds 8

 $tts.SelectVoice("Microsoft Zira Desktop") 
 $Reply = $tts.SpeakAsync("a primitive form of the internet?") 
 Write-Host   -ForegroundColor Yellow "Zyra> a primitive form of the internet?"

 
 "the Original. :-)"
start-sleep -Seconds 10 

 
$tts.SelectVoice("Microsoft Zira Desktop") 
$quip = @('
Excuse me, but I would like to comment.

There is an old Geekish Curse.
It goes, "Be nice to me, or I will replace you with a script." 
Todays Demonstration has been done with a script!"
Just to prove that it is no idle threat. 
')
Write-Host   -ForegroundColor Yellow "Zyra> Comment... Geekish curse"
$tts.SpeakAsync($quip)

$tts.SelectVoice("Microsoft David Desktop") 
$quip2 = @(" Thanks Zira..
Wouldn't it just be nicer to say That 
`"It is getting so that you can automate just about anything with powershell?`"
")
Write-Host   -ForegroundColor Cyan "David> Thanks Zyra...."
$tts.SpeakAsync($quip2)


$tts.SelectVoice("Microsoft Zira Desktop") 
$quip3 = @('Yes, PowerShell Forever!')
 Write-Host   -ForegroundColor Yellow "Zyra: $quip3"
$tts.SpeakAsync($quip3)

start-sleep -Seconds 4
Write-Host   -ForegroundColor Cyan "David> Thank you for viewing our demonstration. "
$tts.SelectVoice("Microsoft David Desktop") 
$closeing = @("
Thank you for viewing our demonstration. 
Visit our Blog: WRITE dash P S at Blog Spot dot com 
")
Write-Host   -ForegroundColor Cyan "David: $closeing"
$tts.SpeakAsync($closeing)


##open closing slide

 "end"






<#
.SYNOPSIS
Send a sequence of keys to an application window

.DESCRIPTION
This Send-Keys script send a sequence of keys to an application window.
To have more information about the key representation look at http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
(C)2013 Massimo A. Santin - Use it at your own risk.

.Source 
https://invista.wordpress.com/2013/08/16/a-simple-powershell-script-to-send-keys-to-an-application-windows/

.PARAMETER ApplicationTitle
The title of the application window

.PARAMETER Keys
The sequence of keys to send

.PARAMETER WaitTime
An optional number of seconds to wait after the sending of the keys

.EXAMPLE
Send-Keys "foobar - Notepad" "Hello world"

Send the sequence of keys "Hello world" to the application titled "foobar - Notepad".

.EXAMPLE
Send-Keys "foobar - Notepad" "Hello world" -WaitTime 5

Send the sequence of keys "Hello world" to the application titled "foobar - Notepad" 
and wait 5 seconds.

.EXAMPLE 
    New-Item foobar.txt -ItemType File; notepad foobar.txt ; Send-Keys "foobar - Notepad" "Hello world{ENTER}Ciao mondo{ENTER}" -WaitTime 1; Send-Keys "foobar - Notepad" "^s"

This command sequence creates a new text file called foobar.txt, opens the file using a notepad,
writes some text and saves the file using notepad.

.LINK
http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
#>
Function Send-Keys {
param (
    [Parameter(Mandatory=$True,Position=1)]
    [string]
    $ApplicationTitle,

    [Parameter(Mandatory=$True,Position=2)]
    [string]
    $Keys,

    [Parameter(Mandatory=$false)]
    [int] $WaitTime
    )

# load assembly cotaining class System.Windows.Forms.SendKeys
[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
#Add-Type -AssemblyName System.Windows.Forms

# add a C# class to access the WIN32 API SetForegroundWindow
Add-Type @"
    using System;
    using System.Runtime.InteropServices;
    public class StartActivateProgramClass {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
    }
"@

# get the applications with the specified title
$p = Get-Process | Where-Object { $_.MainWindowTitle -eq $ApplicationTitle }
if ($p) 
{
    # get the window handle of the first application
    $h = $p[0].MainWindowHandle
    # set the application to foreground
    [void] [StartActivateProgramClass]::SetForegroundWindow($h)

    # send the keys sequence
    # more info on MSDN at http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
    [System.Windows.Forms.SendKeys]::SendWait($Keys)
    if ($WaitTime) 
    {
        Start-Sleep -Seconds $WaitTime
    }
}
}