共用方式為


教學課程:使 Azure Functions 建立前置和後置事件

適用於:✔️ Windows VM ✔️ Linux VM ✔️ 內部部署環境 ✔️ Azure VMs ✔️ 已啟用 Azure Arc 的伺服器。

本教學課程說明如何使用 Azure Functions 建立事前和事後事件,以在排程修補工作流程中啟動和停止 VM。

在本教學課程中,您會了解如何:

  • 必要條件
  • 建立函式應用程式
  • 建立函式
  • 建立事件訂閱

必要條件

  1. 請確定您使用 PowerShell 7.2 Runbook。

  2. 將權限指派給受控識別 - 您可將權限指派給適當的受控識別。 Runbook 可以使用自動化帳戶的系統指派受控識別或使用者指派的受控識別。

    您可使用入口網站或 PowerShell Cmdlet,將權限指派給每個身分識別:

    請遵循使用 Azure 入口網站指派 Azure 角色中的步驟來指派權限


  1. 匯入 Az.ResourceGraph 模組,確定模組已更新至包含模組 2.0.3 版的 ThreadJob。

建立函式應用程式

  1. 請依照步驟來建立函式應用程式

  2. 建立函式應用程式之後,請移至資源,遵循下列步驟,確定您載入相依性:

    注意

    您只需要在第一次載入相依性。 如果 PowerShell 相依性無法載入。 檢查最新版的 AZ 和 AZ。ResourceGraph。

    1. 在 [函式應用程式] 上,選取 [應用程式檔案]

    2. 在 [host.json] 之下,啟用 [ManagedDependecy] 成為 True,然後選取 [requirements.psd1]

    3. 在 [requirements.psd1] 之下,貼上下列程式碼:

       @{
       'Az'='12.*' 
       'Az.ResourceGraph'='1.0.0' 
       'Az.Resources'='6.*' 
       'ThreadJob' = '2.*'
       }
      
    4. 選取 [儲存]。

  3. 從 [概觀] 索引標籤重新啟動函式應用程式,以載入 requirements.psd1 檔案中所提及的相依性。

建立函式

  1. 建立函式應用程式之後,請移至 [資源],然後在 [概觀] 中,選取 [在 Azure 入口網站中建立]

  2. 在 [建立函式] 視窗中,進行下列選取:

    1. 針對 [開發環境屬性],選取 [在入口網站中開發]
    2. 在 [選取範本] 中,選取 [事件方格]
    3. 在 [範本詳細資料] 中,於 [新增函式] 中輸入名稱,然後選取 [建立]此螢幕擷取畫面顯示建立函式時要選取的選項。
  3. 在 [事件方格函式] 中,從左側功能表中選取 [程式碼+測試],貼上下列程式碼,然後選取 [儲存]

    # Make sure that we are using eventGridEvent for parameter binding in Azure function.
    param($eventGridEvent, $TriggerMetadata)
    
    Connect-AzAccount -Identity
    
    # Install the Resource Graph module from PowerShell Gallery
    # Install-Module -Name Az.ResourceGraph
    
    $maintenanceRunId = $eventGridEvent.data.CorrelationId
    $resourceSubscriptionIds = $eventGridEvent.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
        }
    }
    
  4. 從左側功能表中選取 [整合],然後在 [觸發程序] 底下編輯 [事件觸發程序參數名稱]。 使用 [程式碼+測試] 視窗中指定的相同參數名稱。 在此範例中,參數為 eventGridEvent。

    此螢幕擷取畫面顯示 eventGridEvent 參數。

  5. 選取儲存

建立事件訂閱

  1. 登入 [Azure 入口網站],然後移至 [Azure 更新管理員]
  2. 在 [管理] 底下,選取 [機器]、[維護設定]
  3. 在 [維護組態] 頁面上,選取組態。
  4. 在 [設定] 之下,選取 [事件]
  5. 選取 [+ 事件訂用帳戶] 以建立維護前/後的事件。
  6. 在 [建立事件訂用帳戶] 頁面上,輸入下列詳細資料:
    1. 在 [事件訂用帳戶詳細資料] 區段中,提供適當的名稱。
    2. 將結構描述保留為 [事件方格結構描述]
    3. 在 [事件類型] 區段中,[篩選至事件類型]
      1. 針對事前事件選取 [維護前事件]
        • 在 [端點詳細資料] 區段中,選取 [Azure 函式] 端點,然後選取 [設定端點]
        • 提供適當的詳細資料,例如資源群組、函式應用程式來觸發事件。
      2. 針對事後事件選取 [維護後事件]
        • 在 [端點詳細資料] 區段中,選取 [Azure 函式] 端點,然後選取 [設定端點]
        • 提供適當的詳細資料,例如 [資源群組]、[函式應用程式] 來觸發事件。
  7. 選取 建立

您也可使用 Azure 儲存體帳戶和事件中樞來儲存、傳送和接收事件。 深入了解如何建立事件中樞儲存體佇列

下一步