我遇到ping问题导致屏幕“滚动”的问题。我正在使用此代码:
$servers = "192.168.2.10","192.168.2.80","192.168.2.254"
$collection = $()
foreach ($server in $servers)
{
$status = @{ "ServerName" = $server; "TimeStamp" = (Get-Date -f s) }
$testconnection = (Test-Connection $server -Count 1 -ea 0)
$response = ($testconnection | select ResponseTime)
if ($response)
{
$status["Results"] = "Up"
$status["Responsetime"] = $response
}
else
{
$status["Results"] = "Down"
}
New-Object -TypeName PSObject -Property $status -OutVariable serverStatus
$collection += $serverStatus
}
$collection | Export-Csv -Path ".\ServerStatus.csv" -NoTypeInformation
我想为ResponseTime创建一个循环 我现在使用的代码给出了一个响应。 当我给出2的计数时,它会在每个IP-adres旁边打印ResponseTime。
输出:
TimeStamp Responsetime Results ServerName
--------- ------------ ------- ----------
2014-10-22T23:30:17 {@{ResponseTime=6}, @{ResponseTime=4}} Up 192.168.2.10
2014-10-22T23:30:18 Down 192.168.2.80
2014-10-22T23:30:25 {@{ResponseTime=1}, @{ResponseTime=3}} Up 192.168.2.254
我想要的是,脚本会在每个下面打印每个ResponseTime:
TimeStamp Responsetime Results ServerName
--------- ------------ ------- ----------
2014-10-22T23:11:50 @{ResponseTime=419} Up 192.168.2.10
2014-10-22T23:11:51 @{ResponseTime=415} Up 192.168.2.10
2014-10-22T23:11:51 Down 192.168.2.80
2014-10-22T23:11:52 @{ResponseTime=470} Up 192.168.2.254
2014-10-22T23:11:52 @{ResponseTime=7} Up 192.168.2.254
或者像这样:
TimeStamp Responsetime Results ServerName
--------- ------------ ------- ----------
2014-10-22T23:11:50 @{ResponseTime=419} Up 192.168.2.10
2014-10-22T23:11:51 Down 192.168.2.80
2014-10-22T23:11:51 @{ResponseTime=415} Up 192.168.2.254
2014-10-22T23:11:52 @{ResponseTime=470} Up 192.168.2.10
2014-10-22T23:11:51 Down 192.168.2.80
2014-10-22T23:11:52 @{ResponseTime=7} Up 192.168.2.254
哪一个没关系,我的偏好是第二个
你可以帮我解决这个问题。即使不可能也告诉我。谢谢你, 克里斯
答案 0 :(得分:3)
我迟到了,不是因为其他答案都是错误的,它们都是功能性的,但更重要的是因为没有人指出你正在重新创造轮子。
您测试连接,并指定它的一个错误,它会以静默方式继续保留您的变量null。然后你必须测试变量是否有结果,并以一种方式对待它,或者它是否不以另一种方式对待它。您刚刚完成的是自己的Try / Catch场景。如果您实际使用错误停止,则可以使用内置的Try / Catch。考虑这种方法:
$servers = "www.google.com","localhost","www.amazon.com"
$collection = @()
foreach ($server in $servers)
{
Try{
$testconnection = Test-Connection $server -Count 2 -ErrorAction Stop
$testconnection | ForEach{$collection += New-Object PSObject -Property ([ordered]@{
'TimeStamp' = Get-Date -Format s
'Server' = $server
'ResponseTime' = $_.responsetime
'Results' = 'Up'})
}
}
Catch{
$collection += New-Object PSObject -Property ([ordered]@{
'TimeStamp' = Get-Date -Format s
'Server' = $server
'ResponseTime' = $null
'Results' = 'Unreachable'
})
}
}
$collection #| Export-Csv -Path ".\ServerStatus.csv" -NoTypeInformation
尝试ping服务器,如果可以的话,它会将自定义对象添加到带有所需信息的$ collection数组中。如果ping失败,它还会向$ collection添加一个对象,表明服务器无法访问。
另外,你有$collection = $()
。我假设您正在尝试创建一个空数组,该数组已正确完成$collection = @()
(在我建议的代码中已更正)。现在,我注释掉了Export-CSV,所以我可以看到结果。这就是我所看到的:
TimeStamp Server ResponseTime Results
--------- ------ ------------ -------
2014-10-22T17:54:22 www.google.com 9 Up
2014-10-22T17:54:22 www.google.com 12 Up
2014-10-22T17:54:23 localhost 0 Up
2014-10-22T17:54:23 localhost 0 Up
2014-10-22T17:54:27 www.amazon.com Unreachable
亚马逊并没有让我对它进行ping操作,因此它显示为无法访问。
继续讨论为什么您想要的结果不实用...您描述的内容显示您在不连续的时间内ping服务器并从中获取结果。要做到这一点,你必须做-count 1
,并循环两次ForEach循环,所以它会ping服务器1获得1个结果,然后服务器2获得1个结果,然后服务器3获得1个结果。然后它将返回并ping服务器1以获得第二个结果,然后服务器2获得第二个结果,然后服务器3获得第二个结果。如果你想这样做我可以想,它应该给你你想要的结果,你必须做这样的事情:
$servers = "www.google.com","localhost","www.amazon.com"
$collection = @()
$count = 2
for($i=1;$i -le $count;$i++){
ForEach($server in $servers){
do stuff to ping servers as described above, except change -count to 1
}
}
$collection | export-CSV '.\ServerStatus.csv' -notype
这将为您提供所需的结果,但速度较慢。如果你必须针对多个服务器运行它,它将明显变慢。对于列出的那三台服务器,整个过程从使用3.7240945秒到7.6104075秒(大约两倍)。
答案 1 :(得分:1)
而不是
$response = ($testconnection | select ResponseTime)
if ($response)
{
$status["Results"] = "Up"
$status["Responsetime"] = $response
}
DO
if($testconnection)
{
$testconnection | % {
$status = @{"ServerName" = $server; "TimeStamp" = (Get-Date -f s); "Results" = "Up"; "Responsetime"= $_.responsetime};
New-Object -TypeName PSObject -Property $status -OutVariable serverStatus;
$collection += $serverStatus }
}
else
{
$status = @{"ServerName" = $server; "TimeStamp" = (Get-Date -f s); "Results" = "Down"};
New-Object -TypeName PSObject -Property $status -OutVariable serverStatus;
$collection += $serverStatus
}
问题是如果$testconnection
的计数大于1,则$response
或在您的情况下Test-Connection
是一个数组,因此您必须遍历它并添加单个条目到你的收藏。
另外,为了获得价值而不是胡言乱语,你必须调用.responsetime
属性。
答案 2 :(得分:0)
希望我没有把它变得太复杂我提出这个解决方案
$servers = "10.50.10.100","8.8.8.8","169.254.54.1"
$servers | ForEach-Object{
$server = $_
$timeStamp = (Get-Date -f s)
$testconnection = Test-Connection $server -Count 2 -ErrorAction 0
If(!$testconnection){
$props = @{
Server = $server
TimeStamp = $timeStamp
ResponseTime = ""
Results = "Down"
}
New-Object -TypeName PSObject -Property $props
} Else {
$testconnection | ForEach-Object{
$_ | Select-Object @{l='Server';e={$server}},@{l='TimeStamp';e={$timeStamp}},@{l='ResponseTime';e={$_.ResponseTime}},@{l='Results';e={"Up"}}
}
}
} | Export-Csv -Path ".\ServerStatus.csv" -NoTypeInformation
所以你的逻辑仍在这里,但正如你所看到的,有些东西已被改变。 Paul是对的,因为你需要为你拥有的每个ResponseTime
元素循环。我也已经这样做了,但是采用了一种不同的方法,如果没有其他方法,将向您展示PowerShell中的一些功能。分解代码
$servers
导入ForEach-Object
。 ForEach工作正常然而我想跳过保存变量并直接输出到Export-CSV
这就是我改变它的原因。 Test-Connection
或由于某种原因出现错误,那么您需要创建一个对象来表示它。使用所需的属性,使用所需的值构建对象。这是输出到管道而不是使用临时变量。Select-Object
输出所需的值。我代表标签和e代表表达。是的,您可以轻松地使用另一个$ props变量。只是说明另一种选择。 ForEach
,我们可以直接输出到Export-CSV
示例输出
Server TimeStamp ResponseTime Results
------ --------- ------------ -------
10.50.10.100 2014-10-22T20:22:01 0 Up
10.50.10.100 2014-10-22T20:22:01 0 Up
8.8.8.8 2014-10-22T20:22:02 43 Up
8.8.8.8 2014-10-22T20:22:02 39 Up
169.254.54.1 2014-10-22T20:22:03 Down