<# ----------------------------------------------------------------------------- Script: Countdown2.ps1 Version: 0.9 Author: Jeffery Hicks http://jdhitsolutions.com/blog http://twitter.com/JeffHicks http://www.ScriptingGeek.com Date: 4/27/2012 Keywords: Comments: This is a variation on the Start-Countdown script from Josh Atwell (http://www.vtesseract.com/post/21414227113/start-countdown-function-a-visual-for-start-sleep) "Those who forget to script are doomed to repeat their work." **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** ----------------------------------------------------------------------------- #> Function Start-Countdown { <# .Synopsis Initiates a countdown before running a command .Description This is a variation on the Start-Countdown script from Josh Atwell (http://www.vtesseract.com/post/21414227113/start-countdown-function-a-visual-for-start-sleep). It can be used instead of Start-Sleep and provides a visual countdown progress during "sleep" times. At the end of the countdown, your command will execute. Press the ESC key any time during the countdown to abort. USING START-COUNTDOWN IN THE POWERSHELL ISE Results will vary slightly in the PowerShell ISE. If you use this in the ISE, it is recommended to use -Clear. You also cannot use the ESC key to abort the script if using the console. You'll need to press Ctrl+C. If using the progress bar, there is a Stop button in the ISE. If you abort in the ISE, you won't get the warning message. .Parameter Seconds The number of seconds to countdown. The default is 10. .Parameter Scriptblock A PowerShell scriptblock to execute at the end of the countdown. .Parameter ProgressBar Use a progress bar instead of the console. .Parameter Clear Clear the screen. Other wise, the countdown will use the current location. .Parameter Message The message to be displayed at the end of the countdown before any scriptblock is executed. .Example PS C:\> Start-Countdown -Seconds 10 -clear This method will clear the screen and display descending seconds .Example PS C:\> Start-Countdown -Seconds 30 -ProgressBar -scriptblock {get-service -comp (get-content computers.txt)} This method will display a progress bar on screen. At the end of the countdown the scriptblock will execute. .Link http://jdhitsolutions.com/blog .Link Write-Progress #> Param( [Parameter(Position=0,HelpMessage="Enter seconds to countdown from")] [Int]$Seconds = 10, [Parameter(Position=1,Mandatory=$False, HelpMessage="Enter a scriptblock to execute at the end of the countdown")] [scriptblock]$Scriptblock, [Switch]$ProgressBar, [Switch]$Clear, [String]$Message = "Blast Off!" ) #save beginning value for total seconds $TotalSeconds=$Seconds #get current cursor position $Coordinate = New-Object System.Management.Automation.Host.Coordinates $Coordinate.X=$host.ui.rawui.CursorPosition.X $Coordinate.Y=$host.ui.rawui.CursorPosition.Y If ($clear) { Clear-Host #find the middle of the current window $Coordinate.X=[int]($host.ui.rawui.WindowSize.Width/2) $Coordinate.Y=[int]($host.ui.rawui.WindowSize.Height/2) } #define the Escape key $ESCKey = 27 #define a variable indicating if the user aborted the countdown $Abort=$False while ($seconds -ge 1) { if ($host.ui.RawUi.KeyAvailable) { $key = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyUp,IncludeKeyDown") if ($key.VirtualKeyCode -eq $ESCkey) { #ESC was pressed so quit the countdown and set abort flag to True $Seconds = 0 $Abort=$True } } If($ProgressBar){ #calculate percent time remaining, but in reverse so the progress bar #moves from left to right $percent=100 - ($seconds/$TotalSeconds)*100 Write-Progress -Activity "Countdown" -SecondsRemaining $Seconds -Status "Time Remaining" -PercentComplete $percent Start-Sleep -Seconds 1 } Else { if ($Clear) { Clear-Host } $host.ui.rawui.CursorPosition=$Coordinate #write the seconds with padded trailing spaces to overwrite any extra digits such #as moving from 10 to 9 $pad=($TotalSeconds -as [string]).Length if ($seconds -le 10) { $color="Red" } else { $color="Green" } Write-Host "$(([string]$Seconds).Padright($pad))" -foregroundcolor $color Start-Sleep -Seconds 1 } #decrement $Seconds $Seconds-- } #while if ($Progress) { #set progress to complete Write-Progress -Completed } if (-Not $Abort) { if ($clear) { #if $Clear was used, center the message in the console $Coordinate.X=$Coordinate.X - ([int]($message.Length)/2) } $host.ui.rawui.CursorPosition=$Coordinate Write-Host $Message -ForegroundColor Green #run the scriptblock if specified if ($scriptblock) { Invoke-Command -ScriptBlock $Scriptblock } } else { Write-Warning "Countdown aborted" } } #end function