教學課程:透過自動化使用 Webhook 建立前置和後置事件
適用於:✔️ Windows VM ✔️ Linux VM ✔️ 內部部署環境 ✔️ Azure VMs ✔️ 已啟用 Azure Arc 的伺服器。
前置和後置事件,也稱為前置/後置指令碼,可讓您在排程修補程式安裝前後執行使用者定義的動作。 最常見的案例之一是啟動和停止虛擬機器 (VM)。 透過前置事件,您可以執行預先修補指令碼來啟動 VM,再起始排程修補程序。 排程修補完成且伺服器重新啟動後,就可以執行修補後置指令碼,以安全地關閉 VM。
本教學課程說明如何使用 Webhook 建立前置和後置事件,以在排程修補工作流程中啟動和停止 VM。
在本教學課程中,您會了解如何:
- 必要條件
- 建立及發佈自動化 Runbook
- 新增 Webhook
- 建立事件訂閱
必要條件
請確定您使用 PowerShell 7.2 Runbook。
將權限指派給受控識別 - 您可將權限指派給適當的受控識別。 Runbook 可以使用自動化帳戶的系統指派受控識別或使用者指派的受控識別。
您可使用入口網站或 PowerShell Cmdlet,將權限指派給每個身分識別:
請遵循使用 Azure 入口網站指派 Azure 角色中的步驟來指派權限
- 匯入
Az.ResourceGraph
模組,確定模組已更新至包含模組 2.0.3 版的 ThreadJob。
建立及發佈自動化 Runbook
登入 Azure 入口網站,然後移至 [Azure 自動化] 帳戶
如果您使用在 Azure 自動化更新管理中用於前置和後置工作的 Runbook,請務必遵循下列步驟,以避免對機器造成非預期的影響,且維護執行失敗。
針對 Runbook,剖析 Webhook 承載以確保其只會在 Microsoft.Maintenance.PreMaintenanceEvent 或 Microsoft.Maintenance.PostMaintenanceEvent 事件上觸發。 如果有任何其他事件以相同的端點新增,則設計上會在其他訂用帳戶事件上觸發 Webhook。
- 請參閱 Azure 事件方格結構描述。
- 請參閱維護設定特有的 Azure 事件方格結構描述
- 請參閱下列程式碼:
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 }
SoftwareUpdateConfigurationRunContext 參數,其中包含更新部署中機器清單的相關資訊,當您在使用自動化 Webhook 時,不會將其用於前置和後置事件的前置和後置指令碼。 您可以從 Azure Resource Graph 查詢機器清單,或讓機器清單在指令碼中進行編碼。
請參閱 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 } }
若要自訂,您可以使用已完成上述修改的現有指令碼,或使用下列指令碼。
範例指令碼
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
}
}
新增 Webhook
將 Webhook 新增至上述已發佈的 Runbook,並複製 Webhook URL。
注意
在建立 Webhook 之後請務必複製 URL,因為您無法再次擷取該 URL。
建立事件訂閱
在 [管理] 底下,選取 [機器]、[維護設定]。
在 [維護組態] 頁面上,選取組態。
在 [設定] 之下,選取 [事件]。
選取 [+ 事件訂用帳戶] 以建立維護前/後的事件。
在 [建立事件訂用帳戶] 頁面上,輸入下列詳細資料:
選取 建立。
下一步
- 深入了解 Azure Update Manager 中前置和後置事件的概觀。
- 深入了解如何建立前置和後置事件
- 若要了解如何管理維護前和維護後事件或取消排程執行,請參閱維護前和維護後事件維護設定。
- 深入了解如何使用 Azure Functions 建立前置和後置事件。