我有以下代码:
$Servers = "8.8.8.8"
$TimeStart = Get-Date
$TimeEnd = $TimeStart.AddMinutes(1)
Do {
Foreach($s in $Servers) {
$Timeout = 1
$Ping = New-Object System.Net.NetworkInformation.Ping
$Response = $Ping.Send($s,$Timeout)
$Response.Status
$TimeNow = Get-Date
}
}
Until ($TimeNow -ge $TimeEnd)
但是它似乎经常运行。理想情况下,我希望每秒进行一次ping,持续一分钟,如果ping花费的时间超过5毫秒,请记录“ TimedOut”,如果记录时间少于5毫秒,则记录“成功”。另外,输出日期也将很有用。
我将如何操纵此代码来实现这一目标?
答案 0 :(得分:4)
您可以使用Test-Connection
来执行此操作。这是一种方法,稍加修改即可获取所需的其他信息:
Test-Connection -ComputerName $servers -Delay 1 -Count 60 |
Add-Member -MemberType NoteProperty -Name Date -Value (Get-Date) -PassThru |
Add-Member -MemberType NoteProperty -Name Status -Value $(if($_.ResponseTime -gt 5){"Failed"}else{"Succeeded"}) -PassThru
这将每秒$servers
ping每台服务器60秒,并输出具有两个新属性的标准对象:Date
(ping的日期时间)和Status
(是成功还是失败?)
您可以捕获它们,在屏幕上显示它们或发送到文件。例如,要通过保存为CSV记录数据,只需添加以下内容:
| Export-Csv .\ping.csv
CSV将包含比您需要的更多的信息,因此您可以选择导出的内容,也可以直接忽略不需要的内容并使用您要做的部分。
编辑:显示自定义属性
要在控制台中查看自定义属性,请附加以下内容:
| Format-Table PsComputerName, Date, ResponseTime, Status
答案 1 :(得分:1)
以下脚本使用带有-Count 1
的Test-Connection和测试之间的可配置延迟以及定义成功/超时的阈值。
## Q:\Test\2018\07\13\SO_51327101.ps1
$Servers = "8.8.8.8","8.8.4.4","62.220.18.8","89.246.64.8"
$TimeStart = Get-Date
$TimeEnd = $TimeStart.AddMinutes(2)
$Treshold = 12
$DelayMS = 1500
Do {
Foreach($Server in $Servers) {
$Response = Test-Connection $Server -Count 1
$Status = 'Success '
If ($Response.ResponseTime -gt $Treshold){$Status = 'TimedOut'}
"[{0}] {1} Server: {2,15} Responsetime: {3,3} ms" -f `
(Get-Date -f yyyyMMddHHmmss),
$Status,
$Server,
$Response.ResponseTime
}
Start-Sleep -Milliseconds $DelayMS
} Until ((Get-Date) -ge $TimeEnd)
样本输出
[20180713172651] TimedOut Server: 89.246.64.8 Responsetime: 13 ms
[20180713172653] Success Server: 8.8.8.8 Responsetime: 12 ms
[20180713172653] Success Server: 8.8.4.4 Responsetime: 12 ms
[20180713172653] Success Server: 62.220.18.8 Responsetime: 7 ms
[20180713172653] TimedOut Server: 89.246.64.8 Responsetime: 13 ms
答案 2 :(得分:0)
此人使用工作流允许并行ping。它还考虑到System.Net.NetworkInformation.Ping超时在使用低毫秒数时不是精确的。我建议使用BoxDogs Answer,因为它最符合Powershell标准。但我想加入乐趣和学习。
workflow AdvPing([string[]]$Servers, [timespan]$RunTimeLength, [timespan]$Freqency, [timespan]$PingTimeout){
foreach -parallel ($Server in $Servers)
{
$Runtime = (get-date).Add($RunTimeLength)
$CurrentDate = get-date
$Timeout = $PingTimeout
$Ping = New-Object System.Net.NetworkInformation.Ping
while($CurrentDate -le $RunTime){
$Response = ""
$ResponseMessage = ""
$CurrentFreqency = (Get-Date).add($Freqency)
try{
$Response = $Ping.Send($Server,$Timeout.TotalMilliseconds)
if(($Response.RoundtripTime -gt $PingTimeout.Milliseconds) -and ($Response.Status -like "Success")){
$ResponseMessage = "TimeOut"
}else{
$ResponseMessage = $Response.Status
}
$Reply = New-Object psobject -Property @{
Server = $Server
Response = $ResponseMessage
Date = $(get-date).DateTime
Time = $Response.RoundtripTime
Exception = $null
}
}catch{
$Reply = New-Object psobject -Property @{
Server = $Server
Response = "No Host"
Date = $(get-date).DateTime
Time = $null
Exception = $_
}
}
$Reply
$CurrentDate = Get-Date
[timespan]$Wait = $CurrentFreqency - $CurrentDate
try{
sleep -Milliseconds $Wait.TotalMilliseconds
}catch{}
}
}
}
$Servers = @("8.8.8.8", "8.8.4.4", "StackOverflow.com","243.42.432.44")
advping -Servers $Servers -RunTimeLength ([TimeSpan]::FromSeconds(60)) -Freqency ([TimeSpan]::FromSeconds(1)) -PingTimeout ([TimeSpan]::FromMilliseconds(5)) | format-table Date,Server,Response,Time
输出看起来像
Date Server Response Time
---- ------ -------- ----
Friday, July 13, 2018 2:53:37 PM 243.42.432.44 No Host
Friday, July 13, 2018 2:53:37 PM StackOverflow.com TimeOut 15
Friday, July 13, 2018 2:53:37 PM 8.8.4.4 Success 2
Friday, July 13, 2018 2:53:37 PM 8.8.8.8 Success 2
Friday, July 13, 2018 2:53:38 PM 243.42.432.44 No Host
Friday, July 13, 2018 2:53:38 PM StackOverflow.com TimeOut 15
Friday, July 13, 2018 2:53:38 PM 8.8.4.4 Success 2
Friday, July 13, 2018 2:53:38 PM 8.8.8.8 Success 2