Compartilhar via


Tutorial: Criar pré e pós-eventos usando um webhook com automação

Aplica-se a: ✔️ VMs do Windows ✔️ VMs do Linux ✔️ Ambiente local ✔️ VMs do Azure ✔️ Servidores habilitados para Azure Arc.

Pré e pós-eventos, também conhecidos como pré/pós-scripts, permitem executar ações definidas pelo usuário antes e depois da instalação do patch de agendamento. Um dos cenários mais comuns é iniciar e parar uma Máquina Virtual (VM). Com os pré-eventos, você pode executar um script de pré-carregamento para iniciar a VM antes de iniciar o processo de aplicação de patch de agendamento. Depois que a aplicação de patch de agendamento for concluída e o servidor for reinicializado, um script pós-aplicação de patch poderá ser executado para desligar a VM com segurança.

Este tutorial explica como criar pré e postar eventos para iniciar e parar uma VM em um fluxo de trabalho de patch de agendamento usando um webhook.

Neste tutorial, você aprenderá a:

  • Pré-requisitos
  • Criar e publicar runbook de Automação
  • Adicionar webhooks
  • Criar uma assinatura de evento

Pré-requisitos

  1. Verifique se você está usando o runbook do PowerShell 7.2.

  2. Atribuir permissão a identidades gerenciadas – você pode atribuir permissões à identidade gerenciada apropriada. O runbook pode usar a identidade gerenciada atribuída pelo sistema ou pelo usuário da conta de Automação.

    Você pode usar cmdlets do portal ou do PowerShell para atribuir permissões a cada identidade:

    Siga as etapas em Atribuir funções do Azure usando o portal do Azure para atribuir permissões


  1. Importe o módulo Az.ResourceGraph, verifique se o módulo foi atualizado para o ThreadJob com o módulo versão 2.0.3.

Criar e publicar runbook de Automação

  1. Entre no portal do Azure e acesse sua conta da Automação do Azure.

  2. Criar e Publicar um runbook de Automação.

  3. Se você estava usando runbooks que estavam sendo usados para tarefas pré ou pós no Gerenciamento de Atualizações da Automação do Azure, é fundamental que você siga as etapas abaixo para evitar um impacto inesperado em seus computadores e execuções de manutenção com falha.

    1. Para seus runbooks, analise o conteúdo do webhook para garantir que ele esteja disparando apenas em eventos Microsoft.Maintenance.PreMaintenanceEvent ou Microsoft.Maintenance.PostMaintenanceEvent. Por meio do design, os webhooks serão disparados em outros eventos de assinatura se qualquer outro evento for adicionado com o mesmo ponto de extremidade.

      param 
      (  
        [Parameter(Mandatory=$false)]  
        [object] $WebhookData  
      
      )  
      $notificationPayload = ConvertFrom-Json -InputObject $WebhookData.RequestBody  
      $eventType = $notificationPayload[0].eventType  
      
      if ($eventType -ne "Microsoft.Maintenance.PreMaintenanceEvent" -and $eventType –ne "Microsoft.Maintenance.PostMaintenanceEvent" ) {  
        Write-Output "Webhook not triggered as part of pre or post patching for maintenance run"  
      return  
      } 
      
    2. O parâmetro SoftwareUpdateConfigurationRunContext, que contém informações sobre a lista de computadores na implantação de atualização, não será passado para os scripts pré ou pós quando você usá-los para eventos pré ou pós ao usar o webhook de automação. Você pode consultar a lista de computadores do Azure Resource Graph ou ter a lista de computadores codificados nos scripts.

    3. Consulte conteúdo do webhook

      param   
      (   
          [Parameter(Mandatory=$false)]   
          [object] $WebhookData   
      )   
      
      Connect-AzAccount -Identity   
      
      # Install the Resource Graph module from PowerShell Gallery   
      # Install-Module -Name Az.ResourceGraph   
      
      $notificationPayload = ConvertFrom-Json -InputObject $WebhookData.RequestBody   
      $maintenanceRunId = $notificationPayload[0].data.CorrelationId   
      $resourceSubscriptionIds = $notificationPayload[0].data.ResourceSubscriptionIds   
      
      if ($resourceSubscriptionIds.Count -gt 0) {    
      
          Write-Output "Querying ARG to get machine details[MaintenanceRunId=$maintenanceRunId][ResourceSubscriptionIdsCount=$($resourceSubscriptionIds.Count)]"    
          $argQuery = @"maintenanceresources     
          | where type =~ 'microsoft.maintenance/applyupdates'    
          | where properties.correlationId =~ '$($maintenanceRunId)'  
          | where id has '/providers/microsoft.compute/virtualmachines/'    
          | project id, resourceId = tostring(properties.resourceId)    
          | order by id asc 
      "@  
      
      Write-Output "Arg Query Used: $argQuery"    
      $allMachines = [System.Collections.ArrayList]@()    
      $skipToken = $null     
      $res = Search-AzGraph -Query $argQuery -First 1000 -SkipToken $skipToken -Subscription $resourceSubscriptionIds    
      $skipToken = $res.SkipToken    
      $allMachines.AddRange($res.Data)    
      } while ($skipToken -ne $null -and $skipToken.Length -ne 0)  
      
      if ($allMachines.Count -eq 0) {    
      Write-Output "No Machines were found."    
      break    
      }
      }
      
    4. Para personalizar, você pode usar seus scripts existentes com as modificações acima ou usar os scripts a seguir.

Scripts de exemplo

param 
( 
    [Parameter(Mandatory=$false)] 
    [object] $WebhookData 
) 
Connect-AzAccount -Identity 

# Install the Resource Graph module from PowerShell Gallery 
# Install-Module -Name Az.ResourceGraph 

$notificationPayload = ConvertFrom-Json -InputObject $WebhookData.RequestBody 
$eventType = $notificationPayload[0].eventType 

if ($eventType -ne "Microsoft.Maintenance.PreMaintenanceEvent") { 
    Write-Output "Webhook not triggered as part of pre-patching for maintenance run" 
    return 
} 

$maintenanceRunId = $notificationPayload[0].data.CorrelationId 
$resourceSubscriptionIds = $notificationPayload[0].data.ResourceSubscriptionIds 

if ($resourceSubscriptionIds.Count -eq 0) { 
    Write-Output "Resource subscriptions are not present." 
    break 
} 
 
Write-Output "Querying ARG to get machine details [MaintenanceRunId=$maintenanceRunId][ResourceSubscriptionIdsCount=$($resourceSubscriptionIds.Count)]" 

$argQuery = @" 
    maintenanceresources  
    | where type =~ 'microsoft.maintenance/applyupdates' 
    | where properties.correlationId =~ '$($maintenanceRunId)' 
    | where id has '/providers/microsoft.compute/virtualmachines/' 
    | project id, resourceId = tostring(properties.resourceId) 
    | order by id asc 
"@ 

Write-Output "Arg Query Used: $argQuery" 

 
$allMachines = [System.Collections.ArrayList]@() 
$skipToken = $null 

do 
{ 
    $res = Search-AzGraph -Query $argQuery -First 1000 -SkipToken $skipToken -Subscription $resourceSubscriptionIds 
    $skipToken = $res.SkipToken 
    $allMachines.AddRange($res.Data) 
} while ($skipToken -ne $null -and $skipToken.Length -ne 0) 

if ($allMachines.Count -eq 0) { 
    Write-Output "No Machines were found." 
    break 
} 

$jobIDs= New-Object System.Collections.Generic.List[System.Object] 
$startableStates = "stopped" , "stopping", "deallocated", "deallocating" 
$allMachines | ForEach-Object { 
    $vmId =  $_.resourceId 
    $split = $vmId -split "/"; 
    $subscriptionId = $split[2];  
    $rg = $split[4]; 
    $name = $split[8]; 

    Write-Output ("Subscription Id: " + $subscriptionId) 
    $mute = Set-AzContext -Subscription $subscriptionId 
    $vm = Get-AzVM -ResourceGroupName $rg -Name $name -Status -DefaultProfile $mute 
    $state = ($vm.Statuses[1].DisplayStatus -split " ")[1] 
    if($state -in $startableStates) { 
        Write-Output "Starting '$($name)' ..." 
        $newJob = Start-ThreadJob -ScriptBlock { param($resource, $vmname, $sub) $context = Set-AzContext -Subscription $sub; Start-AzVM -ResourceGroupName $resource -Name $vmname -DefaultProfile $context} -ArgumentList $rg, $name, $subscriptionId 
        $jobIDs.Add($newJob.Id) 
    } else { 
        Write-Output ($name + ": no action taken. State: " + $state)  
    } 
} 

$jobsList = $jobIDs.ToArray() 
if ($jobsList) 
{ 
    Write-Output "Waiting for machines to finish starting..." 
    Wait-Job -Id $jobsList 
} 
foreach($id in $jobsList) 
{ 
    $job = Get-Job -Id $id 
    if ($job.Error) 
    { 
        Write-Output $job.Error 
    } 
} 

Adicionar webhooks

Adicione webhooks aos runbooks publicados acima e copie as URLs de webhooks.

Observação

Certifique-se de copiar a URL depois de criar um webhook, pois não é possível recuperar a URL novamente.

Crie uma assinatura de evento.

  1. Entre no Portal do Azure e vá para o Gerenciador de Atualizações do Azure.

  2. Em Gerenciar, selecione Computadores, Configurações de Manutenção.

  3. Na página Configuração de Manutenção, selecione a configuração.

  4. Em Configurações, selecione Eventos.

    Captura de tela que mostra as opções para selecionar a opção de menu de eventos.

  5. Selecione +Assinatura de Evento para criar um evento de manutenção pré/pós.

    Captura de tela que mostra as opções para selecionar as assinaturas de eventos.

  6. Na página Criar assinatura de evento, insira os seguintes detalhes:

    1. Na seção Detalhes da assinatura do evento, forneça um nome apropriado.
    2. Mantenha o esquema como Esquema da Grade de Eventos.
    3. Na seção Tipos de Eventos, Filtre para Tipos de Evento.
      1. Selecione Evento de Pré-manutenção para um pré-evento.
        • Na seção Detalhes do Ponto de Extremidade, selecione o ponto de extremidade do Webhook e selecione Configurar um Ponto de Extremidade .
        • Forneça os detalhes apropriados, como a URL do webhook pré-evento para disparar o evento.
      2. Selecione Evento Pós-manutenção para um pós-evento.
        • Na seção Detalhes do Ponto de Extremidade, o ponto de extremidade do Webhook e selecione Configurar um Ponto de Extremidade .
        • Forneça os detalhes apropriados, como a URL do webhook pós-evento para disparar o evento. Captura de tela que mostra as opções para criar as assinaturas de eventos.
  7. Selecione Criar.

Próximas etapas