PowerShell에서 Azure WebJobs를 실행하려고했을 때 생각 외에도 힘들었습니다.

하고 싶은 일



Azure Web App의 무료 플랜으로 웹 앱을 공개하고 있는데, 이 웹 앱에 대해 정기적으로 백업을 위한 스크립트를 움직이고 싶었다.

이런 때에 사용할 수 있는 편리한 기능으로 WebJobs가 있습니다만, 불행히도 무료 플랜에서는 수동 실행만으로, 스케줄 실행을 할 수 없습니다.
그러나 WebJobs는 WebHook을 사용하여 외부에서 작업을 실행할 수 있습니다.
이것을 이용해 외부에서 PowerShell 스크립트로 실행시키는 것으로, 무료 플랜에서도 정기적으로 실행을 할 수 있을까 생각했습니다.

준비



전제로 실행하려는 WebJobs 태스크를 작성했다고 가정합니다.
Azure 포털에서 만든 작업의 ​​속성을 보려면 WebHook을 실행하는 데 필요한 정보(URL, 사용자 이름, 비밀번호)를 작성했으므로 주의해야 합니다.


먼저 해본 것



WebHook URL에 대해 BASIC 인증으로 POST하면 좋을 뿐이므로,
낙승이다! 라고 생각해서 이렇게 썼습니다.
$Cred = New-Object 'System.Management.Automation.PsCredential' $UserName, (ConvertTo-SecureString -AsPlainText -Force -String $Password)
Invoke-RestMethod -Uri $WebHookURL -Method Post -Credential $Cred

그런데 잘 작동하지 않습니다.Error 403 - This web app is stopped.

PowerShell이 ​​아닌 방법이라면 가능했습니다.



매개 변수를 확인하거나 스크립트를 괴롭히는 것이 좋지 않으므로 한 번 PowerShell 이외의 방법으로 시도하기로 결정했습니다.
REST 클라이언트(Chrome 앱의 YARC!)를 사용하여 POST를 던져보세요.



그러면 이것은 202 - Accepted 가 돌아와서 성공했습니다. 작업도 확실히 실행되었습니다.



그렇다면 역시 문제는 PowerShell에있는 것 같습니다. 우~무・・・

유력한 정보 발견



완전히 막혀 포기하고 있었는데, 유력한 정보를 발견했습니다.
  • Azure WebJobs를 개발하고 운영할 때 유용한 정보를 요약했습니다.

  • 언제든지 WebJob을 실행하기위한 API가 Kudu에 제공됩니다. (중략)
    그러나 처음부터 Authentication 헤더를 보내야 하므로 주의해야 합니다.
  • PowerShell's Invoke-RestMethod equivalent of curl -u (Basic Authentication) - Stack Overflow

  • As noted in the comments, this method will not send the Authorization header on the initial request. It waits for a challenge response then re-sends the request with the Authorization header. This will not work for services that require credentials on the initial request.

    흠흠. 처음부터 Authorization 헤더를 송신하지 않으면 안되지만, PowerShell의 Invoke-RestMethod 는 그러한 사양은 되어 있지 않다고. 분명히 이것이 원인 인 것 같습니다.

    이게 어때?



    상기의 Stack Overflow에 회피책의 샘플 코드가 기재되어 있었으므로, 고맙게 copipe 해 주셔서 이러한 코드가 되었습니다.
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $UserName,$Password)))
    Invoke-RestMethod -Uri $WebHookURL -Method Post -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -ContentType "application/json"
    

    이것을 실행하면 성공적으로 성공했습니다.
    Azure 포털에서 확인하면 배치 WebJobs가 실행 중입니다.

    결국 이렇게



    일단 이것으로 PowerShell에서 WebJobs를 실행시키는 데 성공했지만 Invoke-RestMethod 는 실행 후 아무것도 값을 반환하지 않기 때문에 성공했는지 확실히 불안합니다.
    그래서 명령을 Invoke-WebRequest로 바꾸거나 궁극적으로는 이러한 스크립트로 완성했습니다.
    # Authorizationヘッダー用の資格情報作成
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $UserName, $Password)))
    
    try {
        # POST実行
        $Response = Invoke-WebRequest -Uri $WebHookURL -Method Post -Headers @{Authorization = ("Basic {0}" -f $base64AuthInfo)} -ContentType "application/json" -UseBasicParsing -ErrorAction Stop
    }
    catch {
        $Response = $_.Exception.Response
    }
    
    # 成否確認
    if ([int]$Response.StatusCode -ne 202) {
        Write-Error ('Job execution failed - Expected status is "202(Accepted)", but status "{0}({1})" has returned.' -f [int]$Response.StatusCode, $Response.StatusDescription)
    }
    else {
        Write-Host ('Job started successfully.')
    }
    

    이 스크립트를 태스크 스케줄러를 사용해 매일 실행해 주는 것으로, 무료 플랜인 채로 스케줄 실행을 할 수 있습니다.

    감상



    30초에 바삭바삭할 수 있을까 생각했는데, 갓트리 함정에 빠져 버려서 힘들었습니다.

    좋은 웹페이지 즐겨찾기