Powershell脚本:为响应时间创建循环

时间:2014-10-22 21:38:01

标签: powershell scripting

我遇到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

哪一个没关系,我的偏好是第二个

你可以帮我解决这个问题。即使不可能也告诉我。

谢谢你, 克里斯

3 个答案:

答案 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中的一些功能。分解代码

  1. $servers导入ForEach-Object。 ForEach工作正常然而我想跳过保存变量并直接输出到Export-CSV这就是我改变它的原因。
  2. 因此,如果您在不存在的服务器上使用Test-Connection或由于某种原因出现错误,那么您需要创建一个对象来表示它。使用所需的属性,使用所需的值构建对象。这是输出到管道而不是使用临时变量。
  3. 当连接测试成功时,我们需要输出一个或多个变量以匹配返回的数量。
  4. 继续#3,我们使用Select-Object输出所需的值。我代表标签和e代表表达。是的,您可以轻松地使用另一个$ props变量。只是说明另一种选择。
  5. 由于我们在第一步中更改了ForEach,我们可以直接输出到Export-CSV
  6. 示例输出

    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