Powershell-仅当状态码为-ne 200时,我如何才能从foreach循环中返回应用名称?

时间:2018-10-16 12:19:49

标签: powershell foreach

标题说明了一切。我一直从下面的两个foreach循环的每次迭代返回输出(请参见Write-Host和Write-Output行),但是使用此脚本的应用程序(Nagios)无法处理那么多数据。因此,我想一次只返回1个输出。基本上是“所有应用都可以”或“关闭应用:然后列出未返回200响应代码的应用”。 我不知道该怎么做,因为首先使foreach循环正常工作对我来说是一个挑战。

$ok = 0
$warning = 1
$critical = 2
$unknown = 3

$appPool = get-webapplication
$errorcode = 0
$time_errorcode = 0

foreach($a in $appPool) {

    $app = $a.Attributes[0].Value;
    $url = "http://localhost$app/apitest/index"
    $HTTP_Request = [System.Net.WebRequest]::Create($url)
    $HTTP_Response = try{ $HTTP_Request.GetResponse() }catch {$exceptionMessage = $_.Exception.Message
    $exceptionItem = $app}

    [int]$HTTP_Response.StatusCode -ne 200 
    $statuscode = [int]$HTTP_Response.StatusCode
    Write-Host "$app status code: $statuscode"
    if ($HTTP_Response.StatusCode.value__ -ne 200) {
        [int]$errorcode = 1
    }
}

foreach($t in $appPool){
    $app = $t.Attributes[0].Value;
    $url = "http://localhost$app/apitest/index"
    $output = "$PSScriptRoot\10meg.test"
    $start_time = Get-Date

    try {Invoke-WebRequest -Uri $url -OutFile $output} catch {
    $exceptionMessage = $_.Exception.Message
    $exceptionItem = $app
    Write-Output "$app error: $exceptionMessage"}
    Write-Output "$app Time taken: $((Get-Date).Subtract($start_time).milliSeconds) millisecond(s)"
    $timetaken = $((Get-Date).Subtract($start_time).milliSeconds)
    if ($timetaken.StatusCode.value__ -ge 500) {
        [int]$time_errorcode = 1
    }
}
#Uncomment for testing
#Write-Output $time_errorcode
#Write-Output $errorcode

if (($errorcode -eq 0 -and $time_errorcode -eq 0)){exit $ok}
if (($errorcode -eq 1 -and $time_errorcode -eq 0)){exit $critical}
if (($errorcode -eq 0 -and $time_errorcode -eq 1)){exit $warning}
if (($errorcode -eq 1 -and $time_errorcode -eq 1)){exit $critical}
else {exit $unknown}

2 个答案:

答案 0 :(得分:1)

这是我的方法。未测试。只是为了给您一个与之合作的想法。

$appPool = Get-WebApplication
$errorcode = 0
$time_errorcode = 0

# Using a hashset ensures every app is contained only once
$appsDown = New-Object "System.Collections.Generic.HashSet[string]"

foreach($a in $appPool) {
    $app = $a.Attributes[0].Value;
    $url = "http://localhost$app/apitest/index"

    ### Test response code ###

    $HTTP_Request = [System.Net.WebRequest]::Create($url)
    $HTTP_Response = $null
    try {
        $HTTP_Response = $HTTP_Request.GetResponse()
    } catch {
        # for test
        Write-Host $_
    }
    if ($null -eq $HTTP_Response -or [int]$HTTP_Response.StatusCode -ne 200 ) {
        [int]$errorcode = 1
        [void]$appsDown.Add($app)
    }

    ### Test response time ###

    $output = "$PSScriptRoot\10meg.test"
    $start_time = Get-Date
    $timetaken = -1
    try {
        Invoke-WebRequest -Uri $url -OutFile $output
        $timetaken = ((Get-Date) - $start_time).TotalMilliSeconds
    } catch {
        # for test
        Write-Host $_
    }
    if ($timetaken -lt 0 -or $timetaken -ge 500) {
        [int]$time_errorcode = 1
        [void]$appsDown.Add($app)
    }
}

# Output the results here
if ($appsDown.Count -eq 0) {
    Write-Output "All apps okay"
}
else {
    Write-Output ($appsDown.Count.ToString() + "app(s) down")
    $appsDown | sort | foreach {
        Write-Output $_
    }
}

if (($errorcode -eq 0 -and $time_errorcode -eq 0)){exit $ok}
if (($errorcode -eq 1 -and $time_errorcode -eq 0)){exit $critical}
if (($errorcode -eq 0 -and $time_errorcode -eq 1)){exit $warning}
if (($errorcode -eq 1 -and $time_errorcode -eq 1)){exit $critical}
else {exit $unknown}

说明:

$appsDown = New-Object "System.Collections.Generic.HashSet[string]"

创建.NET HashSet的新实例以保存应用程序名称。 (这是一个无序集合,每个值仅存储一次。)

[void]$appsDown.Add($app)

将应用名称添加到集合中。 [void]可以防止该方法的返回值发送到管道。

答案 1 :(得分:0)

这可以帮助您:

$list = @()
Foreach(x in y){
$item = @{}
If(x.error -eq 200){
$item.Name = x.Name
}
$obj = New-Object PSObject -Property $item
$list += $obj
}

添加这些部分将为您提供变量$list中的应用名称列表