As you know, I do a lot of presenting and training. Normally I use the ubiquitous Start-Demo function to run through a demo list of commands. Most of this time this works just fine. But when I'm doing videos, especially for a video project, I want the viewer to focus on the command and not the fact that I'm running a script to execute those commands. What I want is a way to run through a demo script but make it look like I'm typing. Thus was born Start-TypedDemo.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
[cc lang="PowerShell"]
Function Start-TypedDemo {
Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter the name of a text file with your demo commands")]
[ValidateScript({Test-Path $_})]
[string]$File,
[ValidateScript({$_ -gt 0})]
[int]$Pause=100,
[switch]$NoExecute
)
#this is an internal function so I'm not worried about the name
Function PauseIt {
Param()
#wait for a key press
$Running=$true
#keep looping until a key is pressed
While ($Running)
{
if ($host.ui.RawUi.KeyAvailable) {
$key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown")
if ($key) {
$Running=$False
#check the value and if it is q or ESC, then bail out
if ($key -match "q|27") {
Write-Host `r
Return "quit"
}
}
}
start-sleep -millisecond 100
} #end While
} #PauseIt function
#abort if running in the ISE
if ($host.name -match "PowerShell ISE") {
Write-Warning "This will not work in the ISE. Use the PowerShell console host."
Return
}
Clear-Host
#strip out all comments
$commands=Get-Content -Path $file | Where {-NOT $_.StartsWith("#")}
$count=0
#write a prompt using your current prompt function
Write-Host $(prompt) -NoNewline
foreach ($command in $commands) {
$count++
#pause until a key is pressed which will then process the next command
$p=PauseIt
If ($p -eq "quit") {Return}
for ($i=0;$i -lt $command.length;$i++) {
write-host $command[$i] -NoNewline
Start-sleep -Milliseconds $Pause
#if character is a pipe ( | ) pause in case an
#explanation is needed
if ($command[$i] -eq "|") {
$p=PauseIt
If ($p -eq "quit") {Return}
}
}
#Pause until ready to run the command
$p=PauseIt
If ($p -eq "quit") {Return}
Write-host `n
#execute the command unless -NoExecute was specified
if (-NOT $NoExecute) {
Invoke-Expression $command | Out-Default
}
#reset the prompt unless we've just done the last command
if ($count -lt $commands.count) {
Write-Host $(prompt) -NoNewline
}
} #foreach
} #function
[/cc]
Conceptually, this function is pretty simple: take a line of text, turn it into a character array and write each character to the console with a slight pause.
[cc lang="PowerShell"]
for ($i=0;$i -lt $command.length;$i++) {
write-host $command[$i] -NoNewline
Start-sleep -Milliseconds $Pause
[/cc]
The default pause interval is 100 but you can use -Pause to specify a value in milliseconds. This produces the illusion of someone typing a command, but with no mistakes. After the command is typed it is executed.
[cc lang="PowerShell"]
#execute the command unless -NoExecute was specified
if (-NOT $NoExecute) {
Invoke-Expression $command | Out-Default
}
[/cc]
If you want to run through your demo but without running the commands, use the -NoExecute parameter.
One limitation to this version of the script is that your command must be a one-line expression. I have an idea on how to handle multiple lines but haven't had time to develop them yet. But since most of the time demos are relatively simple I'm trusting this won't be much of an obstacle. The function will also ignore any commented lines. But it will maintain your prompt so when you change locations the fact that you are running a function remains hidden.
The function will pause after typing the line until you press any key. It will also pause after a | character in case you want to explain what you are doing. You can press 'q' or ESC at any pause to abort the demo. Because of this, the function will not work in the ISE.
Here's a short video of the function in action.
I have a few other thoughts for improvements but I'd love to hear how this works for you. Download Start-TypedDemo.
UPDATE: Version 2 of this script with many new features can be found at https://jdhitsolutions.com/blog/2011/05/friday-fun-start-typeddemo-v2/