管理前指令碼和後指令碼

前置指令碼和後置指令碼是您在更新部署之前 (前置工作) 和之後 (後置工作) 應在您的 Azure 自動化帳戶中執行的 Runbook。 前置指令碼和後置指令碼會在 Azure 環境中執行,而不是在本機執行。 前置指令碼會在更新部署開始時執行。 在 Windows 中,後置指令碼會在部署結束時及在已設定的任何重新啟動之後執行。 在 Linux 中,後置指令碼會在部署結束後執行,而不會在電腦重新啟動後執行。

前置指令碼和後置指令碼的需求

若要使用 Runbook 作為前置指令碼或後置指令碼,您必須將其匯入您的自動化帳戶中,並發佈 Runbook

目前僅支援 PowerShell 5.1 和 Python 2 Runbook 作為前置/後置指令碼。 目前不支援以其他 Runbook 類型,例如 Python 3、圖形化、PowerShell 工作流程、圖形化 PowerShell 工作流程作為前置/後置指令碼。

前置指令碼和後置指令碼的參數

當您設定前置指令碼和後置指令碼時,可以像排定 Runbook 時一樣傳入參數。 參數會在建立更新部署時定義。 前置指令碼和後置指令碼支援下列類型:

  • [char]
  • [byte]
  • [int]
  • [long]
  • [decimal]
  • [single]
  • [double]
  • [DateTime]
  • [string]

前置指令碼和後置指令碼 Runbook 參數不支援布林值、物件或陣列類型。 這些值會導致 Runbook 失敗。

如果您需要另一種物件類型,您可以在 Runbook 中使用您自己的邏輯將其轉換成另一種類型。

除了標準 Runbook 參數以外,也會提供 SoftwareUpdateConfigurationRunContext 參數 (類型為 JSON 字串)。 如果您在前置指令碼或後置指令碼中定義該參數,更新部署就會自動傳入該參數。 此參數包含更新部署的相關資訊,也就是 SoftwareUpdateconfigurations API 傳回的部分資訊。 以下幾節會定義相關聯的屬性。

SoftwareUpdateConfigurationRunContext 屬性

屬性 類型​ 描述
SoftwareUpdateConfigurationName String 軟體更新設定的名稱。
SoftwareUpdateConfigurationRunId GUID 執行的唯一識別碼。
SoftwareUpdateConfigurationSettings 與軟體更新設定相關的屬性集合。
SoftwareUpdateConfigurationSettings.OperatingSystem int 更新部署的目標作業系統。 1 = Windows 且 2 = Linux
SoftwareUpdateConfigurationSettings.Duration 時間範圍 (HH:MM:SS) 更新部署執行的持續時間上限 (也稱為維護期間),根據 ISO8601,其格式為 PT[n]H[n]M[n]S
範例:02:00:00
SoftwareUpdateConfigurationSettings.WindowsConfiguration 與 Windows 電腦相關的屬性集合。
SoftwareUpdateConfigurationSettings.WindowsConfiguration.excludedKbNumbers String 排除在更新部署外的 KB 清單 (空格分隔)。
SoftwareUpdateConfigurationSettings.WindowsConfiguration.includedKbNumbers String 包含在更新部署內的 KB 清單 (空格分隔)。
SoftwareUpdateConfigurationSettings.WindowsConfiguration.UpdateCategories 整數 1 = "Critical";
2 = "Security"
4 = "UpdateRollUp"
8 = "FeaturePack"
16 = "ServicePack"
32 = "Definition"
64 = "Tools"
128 = "Updates"
SoftwareUpdateConfigurationSettings.WindowsConfiguration.rebootSetting String 更新部署的重新啟動設定。 有效值包括 IfRequiredNeverAlways
SoftwareUpdateConfigurationSettings.LinuxConfiguration 與 Linux 電腦相關的屬性集合。
SoftwareUpdateConfigurationSettings.LinuxConfiguration.IncludedPackageClassifications 整數 0 = "Unclassified"
1 = "Critical"
2 = "Security"
4 = "Other"
SoftwareUpdateConfigurationSettings.LinuxConfiguration.IncludedPackageNameMasks String 包含在更新部署內的套件名稱清單 (空格分隔)。
SoftwareUpdateConfigurationSettings.LinuxConfiguration.ExcludedPackageNameMasks String 排除在更新部署外的套件名稱清單 (空格分隔)。
SoftwareUpdateConfigurationSettings.LinuxConfiguration.RebootSetting String 更新部署的重新啟動設定。 有效值包括 IfRequiredNeverAlways
SoftwareUpdateConfiguationSettings.AzureVirtualMachines 字串陣列 更新部署中 Azure VM 的資源識別碼清單。
SoftwareUpdateConfigurationSettings.NonAzureComputerNames 字串陣列 更新部署中的非 Azure 電腦 FQDN 清單。

下列範例是傳遞至 Linux 電腦的 SoftwareUpdateConfigurationSettings 屬性的 JSON 字串:

"SoftwareUpdateConfigurationSettings": {
     "OperatingSystem": 2,
     "WindowsConfiguration": null,
     "LinuxConfiguration": {
         "IncludedPackageClassifications": 7,
         "ExcludedPackageNameMasks": "fgh xyz",
         "IncludedPackageNameMasks": "abc bin*",
         "RebootSetting": "IfRequired"
     },
     "Targets": {
         "azureQueries": null,
         "nonAzureQueries": ""
     },
     "NonAzureComputerNames": [
        "box1.contoso.com",
        "box2.contoso.com"
     ],
     "AzureVirtualMachines": [
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroupName/providers/Microsoft.Compute/virtualMachines/vm-01"
     ],
     "Duration": "02:00:00",
     "PSComputerName": "localhost",
     "PSShowComputerName": true,
     "PSSourceJobInstanceId": "2477a37b-5262-4f4f-b636-3a70152901e9"
 }

下列範例是傳遞至 Windows 電腦的 SoftwareUpdateConfigurationSettings 屬性的 JSON 字串:

"SoftwareUpdateConfigurationRunContext": {
    "SoftwareUpdateConfigurationName": "sampleConfiguration",
    "SoftwareUpdateConfigurationRunId": "00000000-0000-0000-0000-000000000000",
    "SoftwareUpdateConfigurationSettings": {
      "operatingSystem": "Windows",
      "duration": "02:00:00",
      "windows": {
        "excludedKbNumbers": [
          "168934",
          "168973"
        ],
        "includedUpdateClassifications": "Critical",
        "rebootSetting": "IfRequired"
      },
      "azureVirtualMachines": [
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-01",
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-02",
        "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/vm-03"
      ],
      "nonAzureComputerNames": [
        "box1.contoso.com",
        "box2.contoso.com"
      ]
    }
  }

您可在以下位置找到所有屬性的完整範例:依名稱取得軟體更新組態

注意

SoftwareUpdateConfigurationRunContext 物件可包含機器的重複項目。 這可能會導致前置指令碼和後置指令碼在相同機器上執行多次。 此行為的因應措施是使用 Sort-Object -Unique,僅選取唯一的 VM 名稱。

在部署中使用前置指令碼或後置指令碼

若要在更新部署中使用前置指令碼或後置指令碼,請從建立更新部署開始著手。 選取 [前置指令碼 + 後置指令碼]。 此動作會開啟 [選取更新前 + 更新後指令碼] 頁面。

Select scripts

選取您要使用的指令碼。 在此範例中,我們使用 UpdateManagement-TurnOnVms Runbook。 選取了 Runbook 後,[設定指令碼] 頁面會隨即開啟。 請選取 [前置指令碼],然後選取 [確定]

UpdateManagement-TurnOffVms 指令碼重複此程序。 但在選擇 [指令碼類型] 時,請選取 [後置指令碼]

[選取的項目] 區段現在會顯示您選取的兩個指令碼。 一個是前置指令碼,另一個是後置指令碼:

Selected items

完成更新部署的設定。

更新部署完成後,您可以移至 [更新部署] 來檢視結果。 您可以看到,前置指令碼和後置指令碼的狀態都已提供:

Update results

選取更新部署執行後,您會看到前置指令碼和後置指令碼的其他詳細資料。 其中會顯示該執行進行時的指令碼來源連結。

Deployment run results

停止部署

如果您想要根據前置指令碼停止部署,您必須擲回例外狀況。 若未這麼做,部署和後置指令碼仍將執行。 下列程式碼片段說明如何利用 PowerShell 擲回例外狀況。

#In this case, we want to terminate the patch job if any run fails.
#This logic might not hold for all cases - you might want to allow success as long as at least 1 run succeeds
foreach($summary in $finalStatus)
{
    if ($summary.Type -eq "Error")
    {
        #We must throw in order to fail the patch deployment.
        throw $summary.Summary
    }
}

在 Python 2 中,例外狀況處理由 try 區塊管理。

與機器互動

前置指令碼和後置指令碼會在您的自動化帳戶中以 Runbook 的形式執行,而不是直接在部署中的機器上執行。 前置工作和後置工作也會在 Azure 環境中執行,且無法存取非 Azure 機器。 以下幾節說明如何直接與機器互動,無論是 Azure VM 還是非 Azure 機器。

與 Azure 機器互動

前置工作和後置工作會以 Runbook 的形式執行,而不會在部署中的 Azure VM 上以原生方式執行。 若要與您的 Azure VM 互動,您必須具有下列項目:

  • 受控識別或執行身分帳戶
  • 您想要執行的 Runbook

若要與 Azure 機器互動,您應使用 Invoke-AzVMRunCommand Cmdlet 與您的 Azure VM 互動。 如需執行此作業的範例,請參閱 Runbook 範例:更新管理 – 使用 Run 命令執行指令碼

與非 Azure 機器互動

前置工作和後置工作會在 Azure 環境中執行,且無法存取非 Azure 機器。 若要與非 Azure 機器互動,您必須具備下列項目:

  • 受控識別或執行身分帳戶
  • 已安裝在機器上的混合式 Runbook 背景工作角色
  • 您想要在本機上執行的 Runbook
  • 父 Runbook

若要與非 Azure 機器互動,父 Runbook 需在 Azure 環境中執行。 此 Runbook 會使用 Start-AzAutomationRunbook Cmdlet 來呼叫子 Runbook。 您必須指定 RunOn 參數,並提供混合式 Runbook 背景工作角色的名稱,好讓指令碼在其中執行。 請參閱 Runbook 範例:更新管理 – 在本機執行指令碼

中止修補程式部署

如果您的前置指令碼傳回錯誤,您可能會想要中止部署。 若要這麼做,您必須在指令碼中針對任何會導致失敗的邏輯擲回錯誤。

if (<My custom error logic>)
{
    #Throw an error to fail the patch deployment.
    throw "There was an error, abort deployment"
}

在 Python 2 中,如果您想要在特定狀況發生時擲回錯誤,請使用 raise 語句。

If (<My custom error logic>)
   raise Exception('Something happened.')

範例

如需前置指令碼和後置指令碼的範例,請參閱 Azure 自動化 GitHub 組織PowerShell 資源庫,或透過 Azure 入口網站將其匯入。 若要這麼做,請在您自動化帳戶的 [程序自動化] 下方,選取 [Runbook 資源庫]。 使用 [更新管理] 作為篩選條件。

Gallery list

或者,您可以透過指令碼名稱來搜尋這些範例,如下列清單所示:

  • 更新管理 - 開啟 VM
  • 更新管理 - 關閉 VM
  • 更新管理 - 在本機執行指令碼
  • 更新管理 - 前置/後置指令碼的範本
  • 更新管理 - 以執行命令來執行指令碼

重要

匯入 Runbook 之後,您必須先將其發佈,方能使用。 若要這麼做,請在自動化帳戶中尋找 Runbook,選取 [編輯],然後選取 [發佈]

這些範例都會以下列範例中定義的基底範本為基礎。 此範本可用來建立您自己的 Runbook,以便搭配前置指令碼和後置指令碼使用。 其中包含向 Azure 進行驗證及處理 SoftwareUpdateConfigurationRunContext 參數的必要邏輯。

<#
.SYNOPSIS
 Barebones script for Update Management Pre/Post

.DESCRIPTION
  This script is intended to be run as a part of Update Management pre/post-scripts.
  It requires the Automation account's system-assigned managed identity.

.PARAMETER SoftwareUpdateConfigurationRunContext
  This is a system variable which is automatically passed in by Update Management during a deployment.
#>

param(
    [string]$SoftwareUpdateConfigurationRunContext
)

#region BoilerplateAuthentication
# Ensures you do not inherit an AzContext in your runbook
Disable-AzContextAutosave -Scope Process

# Connect to Azure with system-assigned managed identity
$AzureContext = (Connect-AzAccount -Identity).context

# set and store context
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext
#endregion BoilerplateAuthentication

#If you wish to use the run context, it must be converted from JSON
$context = ConvertFrom-Json $SoftwareUpdateConfigurationRunContext
#Access the properties of the SoftwareUpdateConfigurationRunContext
$vmIds = $context.SoftwareUpdateConfigurationSettings.AzureVirtualMachines | Sort-Object -Unique
$runId = $context.SoftwareUpdateConfigurationRunId

Write-Output $context

#Example: How to create and write to a variable using the pre-script:
<#
#Create variable named after this run so it can be retrieved
New-AzAutomationVariable -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccount -Name $runId -Value "" -Encrypted $false
#Set value of variable
Set-AutomationVariable -Name $runId -Value $vmIds
#>

#Example: How to retrieve information from a variable set during the pre-script
<#
$variable = Get-AutomationVariable -Name $runId
#>

如果您想要 Runbook 以系統指派的受控識別來執行,請將程式碼保持原狀。 如果您偏好使用使用者指派的受控識別,則:

  1. 從第 22 行移除 $AzureContext = (Connect-AzAccount -Identity).context
  2. 將其取代為 $AzureContext = (Connect-AzAccount -Identity -AccountId <ClientId>).context,然後
  3. 輸入用戶端識別碼。

注意

針對非圖形化 PowerShell Runbook,Add-AzAccountAdd-AzureRMAccountConnect-AzAccount \(英文\) 的別名。 您可使用這些 Cmdlet,也可以在您的自動化帳戶中將您的模組更新為最新版本。 即使您才剛建立新的自動化帳戶,可能還是需要更新您的模組。

下一步

如需更新管理的詳細資訊,請參閱管理 VM 的更新和修補程式