问题
My google-fu has failed me. I've got a pretty simple script that just tests ping connectivity from one server to another, and displays a runtime at the top.
I'd like to be able to stop this script at any time with a single keypress ("q" in the script) and have it give some basic stats about how long it ran, and how many times it failed.
I can stop the script with ctrl+c, but that completely exits and doesn't allow me to show any stats. Below is my script. Any help is appreciated!
###############SETTINGS##########################
#Server to Ping:
$RemoteMachine = "ServerNameorIP"
#Seconds between each ping:
$PingInterval = 5
#File to log results:
$outFile = "C:\PingLog\"+$today+".PingLog.txt"
##################################################
$today = Get-Date -Format "yyyy-MM-dd"
#start a stopwatch for the progress bar
$elapsedTime = [system.diagnostics.stopwatch]::StartNew()
while ($true)
{
#Stick a progress bar at the top that shows elapsed time and how often we're pinging:
write-progress -activity "Now testing ping connectivity to $RemoteMachine every $PingInterval seconds. Press q to quit." -status "$([string]::Format("Time Elapsed: {0:d2}:{1:d2}:{2:d2}", $elapsedTime.Elapsed.hours, $elapsedTime.Elapsed.minutes, $elapsedTime.Elapsed.seconds))"
$pingFails = 0
#If the ping test fails, say something, and write it out to a log
if(!(Test-Connection -ComputerName bb-ts-db -Quiet))
{
$pingFails++
$dropTime = Get-Date -Format "MM/dd/yyyy - HH:mm:ss"
Add-Content -Path $outfile -value ("Connection Lost at: $dropTime")
Echo "Connection Lost at $dropTime"
}
#Exit the loop if a key is pressed:
if ($Host.UI.RawUI.KeyAvailable -and ("q" -eq $Host.UI.RawUI.ReadKey("IncludeKeyUp,NoEcho").Character))
{
Write-Host "Exiting now, don't try to stop me...." -Background DarkRed
break;
}
#Wait the preset amount of time between each ping loop
Start-Sleep $pingInterval
}
$elapsedTime.stop()
#Display the stats of this session:
echo "Test runtime: $elapsedTime.Elapsed"
echo "# of failed pings: $pingFails"
#If there WERE ping fails, write stats to $outFile
if($pingFails -gt 0)
{
Add-content -Path $outfile -value "`n `n `n"
Add-content -Path $outfile -value "Test runtime: $elapsedTime.Elapsed"
Add-content -Path $outfile -value "# of failed pings: $pingFails"
}
回答1:
Here is a simple example of using the [console]::KeyAvailable method. To make it usable, you will have to wake up your loop more often, and only execute ping on every 10th (,or so) wake up. (If that makes sense.)
$continue = $true
while($continue)
{
if ([console]::KeyAvailable)
{
echo "Exit with `"q`"";
$x = [System.Console]::ReadKey()
switch ( $x.key)
{
q { $continue = $false }
}
}
else
{
# Your while loop commands go here......
Start-Sleep -Milliseconds 500
}
}
Note: Unfortunately [console]::KeyAvailable does not work in PowerShelISE host so it is a pain to debug :(
回答2:
This post is similar. There CTRL-C is captured and used to quit the loop/script.
Is there a way to catch ctrl-c and ask the user to confirm?
来源:https://stackoverflow.com/questions/29545166/how-to-stop-whiletrue-that-contains-start-sleep-in-powershell