Назад | Перейти на главную страницу

Пробуждение веб-сервера с помощью сценария PowerShell?

Я создаю сценарий, который выполняет HTTP-запрос, чтобы «разбудить» некоторые приложения asp.net.

Следующий скрипт работает, но работает синхронно:

function WakeUp([string] $url)
{
    Write-Host "Waking up $url ..." -NoNewLine
    $client = new-object system.net.WebClient
    $client.UseDefaultCredentials = $true
    $null = $client.OpenRead($url)
    $client.Dispose()
    Write-Host " Ok"

}
# Run your code that needs to be elevated here
@(
    "http://app1/",
    "http://app2/",
    "http://app3/"
 ) | % { WakeUp $_ }

Я бы хотел улучшить этот скрипт, чтобы целевой сайт не просыпался. Фактически, призыв к OpenRead ждет ответа, прежде чем вернуться.

Я пытался использовать OpenReadAsync, но звонок Dispose происходит до того, как запрос будет фактически отправлен, и целевое приложение не проснется.

Какие у меня варианты?

[Редактировать] Применяя предложения Энди Арисменди, мой сценарий теперь:

$WakeUp = {
    Param ([string] $url)
    try 
    {
        Write-Output "Waking up $url ..."
        $client = new-object system.net.WebClient
        $client.UseDefaultCredentials = $true
        $null = $client.OpenRead($url)
        $client.Dispose()
        Write-Output "$url Ok"
    } catch {
        Write-Error $_
        throw $_
    }
}

$jobs = @()
# Run your code that needs to be elevated here
@(
    "http://app1/",
    "http://app2/",
    "http://app3/"
 ) | % { 
    $jobs += Start-Job -ScriptBlock $WakeUp -ArgumentList $_ 
    }

Receive-Job -Job $jobs -Keep
Wait-Job -Job $jobs

Кажется, это работает, как ожидалось, но я теряю Write-Host. Есть мысли?

Фоновые задания могут сделать ваш рабочий процесс асинхронным.

  • Преобразуйте функцию пробуждения в блок скрипта:

    $WakeUp = {
        ([string] $url)
    
        try {
            # Processing...
        } catch {
            throw $_
        }
    }
    
  • Для каждого URL запускайте блок скрипта в качестве фонового задания.

    @(
        "http://app1"
        # More...
    ) | % {
        Start-Job -ScriptBlock $WakeUp -ArgumentList $_
    }
    

Проверить мой ответ из другого вопроса, чтобы увидеть, как вы можете получить данные из фонового задания и определить, какое из них не удалось.

Обновить

Это решает проблему в вашей версии о неполучении вывода. Вы хотите использовать Wait-Job перед Receive-Job чтобы позволить им закончить, потому что они работают асинхронно.

$WakeUp = {
    param ([string] $url)
    try {
        Write-Output "Waking up $url ..."
        Start-Sleep -Seconds 3
        if ($url -eq "http://app2/") {
            throw ($url + " failed")
        }
        Write-Output "$url Ok"
    } catch {
        throw $_
    }
}

$jobs = @()
# Run your code that needs to be elevated here
@(
    "http://app1/",
    "http://app2/",
    "http://app3/"
 ) | % { 
    $jobs += Start-Job -ScriptBlock $WakeUp -ArgumentList $_ 
}

Wait-Job -Job $jobs | Out-Null
Receive-Job -Job $jobs -Keep