Powershell - Как я могу вернуть имя приложения из цикла foreach, только если код состояния -ne 200 - PullRequest
0 голосов
/ 16 октября 2018

Название говорит само за себя.Я возвращал результат каждой итерации обоих приведенных ниже циклов 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 голосов
/ 16 октября 2018

Вот мой подход.UNTESTED.Просто чтобы дать вам представление о том, как работать с

$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] существует для предотвращения отправки возвращаемого значения метода в конвейер.

0 голосов
/ 16 октября 2018

Это может помочь вам:

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

При добавлении этих частей у вас появится список имен приложений в переменной $list

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...