Share via


使用受控執行命令在 Linux VM 中執行指令碼

警告

本文參考 CentOS,這是接近結束生命週期 (EOL) 狀態的 Linux 發行版本。 請據以考慮您的使用和規劃。 如需詳細資訊,請參閱 CentOS 生命週期結束指引

適用於:✔️ Linux VM ✔️ 彈性擴展集

重要

受控執行命令目前可用於 Azure CLI、PowerShell 和 API。 入口網站功能即將推出。

執行命令功能會使用虛擬機器 (VM) 代理程式在 Azure Linux VM 中執行指令碼。 您可以使用這些指令碼,進行一般電腦或應用程式管理。 這些指令碼可協助快速診斷和修復 VM 存取與網路問題,並讓 VM 恢復正常狀態。

「更新的」受控執行命令會使用相同的 VM 代理程式通道來執行指令碼,並透過原始動作導向執行命令提供下列增強功能:

  • 透過 ARM 部署範本支援更新的執行命令
  • 平行執行多個指令碼
  • 循序執行指令碼
  • 使用者指定的指令碼逾時
  • 支援長時間執行 (小時/天) 的指令碼
  • 以安全的方式傳遞秘密 (參數、密碼)

必要條件

支援的 Linux 發行版本

Linux 發行版本 x64 ARM64
Alma Linux 9.x+ 不支援
CentOS 7.x+、8.x+ 不支援
Debian 10+ 不支援
Flatcar Linux 3374.2.x+ 不支援
Azure Linux 2.x 不支援
openSUSE 12.3+ 不支援
Oracle Linux 6.4+、7.x+、8.x+ 不支援
Red Hat Enterprise Linux 6.7+、7.x+、8.x+ 不支援
Rocky Linux 9.x+ 不支援
SLES 12.x+、15.x+ 不支援
Ubuntu 18.04+、20.04+、22.04+ 不支援

限制於執行命令的存取

列出執行命令或顯示命令詳細資料,需要訂用帳戶層級的 Microsoft.Compute/locations/runCommands/read 權限。 內建讀者角色和具有此權限的較高層級。

執行命令需要有 Microsoft.Compute/virtualMachines/runCommand/write 權限。 虛擬機器參與者角色和具有此權限的較高層級。

您可使用其中一個內建角色或建立自訂角色,以使用 [執行] 命令。

Azure CLI

下列範例使用 az vm run-command 在 Azure Linux VM 上執行 Shell 指令碼。

使用 VM 執行指令碼

此命令會將指令碼傳遞至 VM、執行,並傳回擷取的輸出。

az vm run-command create --name "myRunCommand" --vm-name "myVM" --resource-group "myRG" --script "echo Hello World!"

列出 VM 上已部署的所有 RunCommand 資源

此命令會傳回先前部署的執行命令及其屬性的完整清單。

az vm run-command list --vm-name "myVM" --resource-group "myRG"

取得執行狀態和結果

此命令會擷取目前的執行進度,包括最新的輸出、開始/結束時間、結束代碼,以及執行的終端狀態。

az vm run-command show --name "myRunCommand" --vm-name "myVM" --resource-group "myRG" --expand instanceView

注意

instanceView 中的輸出和錯誤欄位限制為最後 4KB。 如果您想存取完整的輸出和錯誤,您可以在使用 Set-AzVMRunCommandSet-AzVMssRunCommand 執行「執行命令」時,透過 -outputBlobUri-errorBlobUri 將輸出和錯誤資料轉送至儲存體附加 Blob。

從 VM 刪除 RunCommand 資源

移除先前部署在 VM 上的 RunCommand 資源。 如果指令碼仍在執行中,則會終止執行。

az vm run-command delete --name "myRunCommand" --vm-name "myVM" --resource-group "myRG"

PowerShell

使用 VM 執行指令碼

此命令會將指令碼傳遞至 VM、執行,並傳回擷取的輸出。

Set-AzVMRunCommand -ResourceGroupName "myRG" -VMName "myVM" -Location "EastUS" -RunCommandName "RunCommandName" –SourceScript "echo Hello World!"

使用 SourceScriptUri 參數在 VM 上執行指令碼

OutputBlobUriErrorBlobUri 是選擇性參數。

Set-AzVMRunCommand -ResourceGroupName -VMName -RunCommandName -SourceScriptUri “< SAS URI of a storage blob with read access or public URI>" -OutputBlobUri “< SAS URI of a storage append blob with read, add, create, write access>” -ErrorBlobUri “< SAS URI of a storage append blob with read, add, create, write access>”

列出 VM 上已部署的所有 RunCommand 資源

此命令會傳回先前部署的執行命令及其屬性的完整清單。

Get-AzVMRunCommand -ResourceGroupName "myRG" -VMName "myVM"

取得執行狀態和結果

此命令會擷取目前的執行進度,包括最新的輸出、開始/結束時間、結束代碼,以及執行的終端狀態。

Get-AzVMRunCommand -ResourceGroupName "myRG" -VMName "myVM" -RunCommandName "RunCommandName" -Expand instanceView

使用 SourceScriptURI (儲存體 Blob SAS URL),在 VM 上建立或更新「執行命令」

使用儲存體 Blob 的 SAS URL (包含 PowerShell 指令碼),在 Windows VM 上建立或更新「執行命令」。 SourceScriptUri 可以是儲存體 Blob 的完整 SAS URL 或公用 URL。

注意

SAS URL 必須提供 Blob 的讀取存取。 SAS URL 的建議到期時間為 24 小時。 您可以使用 Blob 選項在 Azure 入口網站產生 SAS URL,或使用 New-AzStorageBlobSASToken 產生 SAS 權杖。 如果使用 New-AzStorageBlobSASToken 產生 SAS 權杖,您的 SAS URL = "基底 blob URL" + "?" + "來自 New-AzStorageBlobSASToken 的 SAS 權杖"

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location EastUS2EUAP -SourceScriptUri <SourceScriptURI>

建立或更新「執行命令」之後,取得 VM 的「執行命令」執行個體檢視

取得具有執行個體檢視的 VM 執行命令。 執行個體檢視包含「執行命令」的執行狀態 (成功、失敗等等)、結束代碼、標準輸出,以及使用「執行命令」執行指令碼所產生的標準錯誤。 非零的 ExitCode 表示執行失敗。

$x = Get-AzVMRunCommand -ResourceGroupName MyRG -VMName MyVM -RunCommandName MyRunCommand -Expand InstanceView
$x.InstanceView

預期輸出:

ExecutionState   : Succeeded
ExecutionMessage :
ExitCode         : 0
Output           :   
output       : uid=0(root) gid=0(root) groups=0(root)
                   HelloWorld

Error            :
StartTime        : 10/27/2022 9:10:52 PM
EndTime          : 10/27/2022 9:10:55 PM
Statuses         :

InstanceView.ExecutionState:使用者的「執行命令」指令碼狀態。 請參考此狀態,以了解您的指令碼是否成功。

ProvisioningState:一般延伸模組佈建端對端的狀態 (延伸模組平台是否能夠觸發「執行命令」指令碼)。

使用 SourceScript (指令碼文字),在 VM 上建立或更新「執行命令」

在將指令碼內容直接傳遞至 -SourceScript 參數的 VM 上建立或更新「執行命令」。 使用 ; 來分隔多個命令。

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVML -RunCommandName MyRunCommand2 -Location EastUS2EUAP -SourceScript "id; echo HelloWorld"

使用 SourceCommandId 在 VM 上建立或更新「執行命令」

使用預先存在的 commandId 在 VM 上建立或更新「執行命令」。 您可以使用 Get-AzVMRunCommandDocument 來擷取可用的 commandId。

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location EastUS2EUAP -SourceCommandId ipconfig

使用 OutputBlobUri、ErrorBlobUri 在 VM 上建立或更新「執行命令」,以將標準輸出和標準錯誤訊息串流至輸出和錯誤附加 Blob

在 VM 上建立或更新「執行命令」,並將標準輸出和標準錯誤訊息串流至輸出和錯誤附加 Blob。

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVML -RunCommandName MyRunCommand3 -Location EastUS2EUAP EastUS2EUAP -SourceScriptUri <SourceScriptUri> -OutputBlobUri <OutputBlobUri> -ErrorBlobUri <errorbloburi>

注意

輸出和錯誤 Blob 的類型必須為 AppendBlob,且其 SAS URL 必須提供 Blob 的讀取、附加、建立、寫入存取權。 SAS URL 的建議到期時間為 24 小時。 如果輸出或錯誤 Blob 不存在,則會建立 AppendBlob 類型的 Blob。 您可以使用 Blob 選項在 Azure 入口網站產生 SAS URL,或使用 New-AzStorageBlobSASToken 產生 SAS 權杖。 如果使用 New-AzStorageBlobSASToken 產生 SAS 權杖,則 SAS URL = 基底 Blob URL + "?" + New-AzStorageBlobSASToken 中的 SAS 權杖。

在 VM 上建立或更新「執行命令」,使用 RunAsUser 和 RunAsPassword 參數以不同使用者的身分執行「執行命令」

在 VM 上建立或更新「執行命令」,使用 RunAsUserRunAsPassword 參數以不同使用者的身分執行「執行命令」。 若要讓 RunAs 正常運作,請連絡 VM 的管理員,並確定已在 VM 上新增使用者、使用者有權存取「執行命令」所存取的資源 (目錄、檔案、網路等等),而且如果是使用 Windows VM,也需確認 VM 上已執行「次要登入」服務。

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location EastUS2EUAP EastUS2EUAP -SourceScriptUri <SourceScriptUri> -RunAsUser myusername -RunAsPassword mypassword

使用 SourceScriptUri (儲存體 Blob SAS URL),在虛擬機器擴展集資源上建立或更新「執行命令」。

使用儲存體 Blob 的 SAS URL (包含 bash 指令碼),在虛擬機器擴展集資源上建立或更新「執行命令」。

Set-AzVmssVMRunCommand -ResourceGroupName MyRG0 -VMScaleSetName MyVMSS -InstanceId 0 -RunCommandName MyRunCommand -Location EastUS2EUAP -SourceScriptUri <SourceScriptUri>

注意

請注意,SAS URL 必須提供 Blob 的讀取存取。 SAS URL 的建議到期時間為 24 小時。 您可以使用 Blob 選項在 Azure 入口網站產生 SAS URL,或使用 New-AzStorageBlobSASToken 產生 SAS 權杖。 如果使用 New-AzStorageBlobSASToken 產生 SAS 權杖,則 SAS URL = 基底 blob URL + "?" + 來自 New-AzStorageBlobSASToken 的 SAS 權杖。

使用參數和 ProtectedParameter 參數 (指令碼的公用和受保護參數),在 VM 執行個體上建立或更新「執行命令」

$PublicParametersArray = @([Microsoft.Azure.PowerShell.Cmdlets.Compute.Models.Api20210701.IRunCommandInputParameter]@{name='publicParam1';value='publicParam1value'},
>> [Microsoft.Azure.PowerShell.Cmdlets.Compute.Models.Api20210701.IRunCommandInputParameter]@{name='publicParam2';value='publicParam2value'})

$ProtectedParametersArray = @([Microsoft.Azure.PowerShell.Cmdlets.Compute.Models.Api20210701.IRunCommandInputParameter]@{name='secret1';value='secret1value'},
>> [Microsoft.Azure.PowerShell.Cmdlets.Compute.Models.Api20210701.IRunCommandInputParameter]@{name='secret2';value='secret2value'})

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location EastUS2EUAP -SourceScriptUri <SourceScriptUri> -Parameter $PublicParametersArray -ProtectedParameter $ProtectedParametersArray

使用 ProtectedParameter 將任何敏感性輸入 (例如密碼、金鑰等等) 傳遞至指令碼。

  • Windows:參數和 ProtectedParameter 會傳遞至指令碼,因為引數會傳遞至指令碼並執行如下 - myscript.ps1 -publicParam1 publicParam1value -publicParam2 publicParam2value -secret1 secret1value -secret2 secret2value
  • Linux:具名參數及其值會設為環境設定,這應該可在 .sh 指令碼中存取。 針對未具名的引數,則會將空字串傳遞至名稱輸入。 未具名的引數會傳遞至指令碼並執行如下 - myscript.sh publicParam1value publicParam2value secret1value secret2value

從 VM 刪除 RunCommand 資源

移除先前部署在 VM 上的 RunCommand 資源。 如果指令碼仍在執行中,則會終止執行。

Remove-AzVMRunCommand -ResourceGroupName "myRG" -VMName "myVM" -RunCommandName "RunCommandName"

REST API

若要部署新的執行命令,請直接在 VM 上執行 PUT,並為執行命令執行個體指定唯一名稱。

GET /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/<vmName>/runcommands?api-version=2019-12-01
{ 
"location": "<location>", 
"properties": { 
    "source": { 
        "script": "Write-Host Hello World!", 
        "scriptUri": "<SAS URI of a storage blob with read access or public URI>",  
        "commandId": "<Id>"  
        }, 
    "parameters": [ 
        { 
            "name": "param1",
            "value": "value1" 
            }, 
        { 
            "name": "param2", 
            "value": "value2" 
            } 
        ], 
    "protectedParameters": [ 
        { 
            "name": "secret1", 
            "value": "value1" 
            }, 
        { 
            "name": "secret2", 
            "value": "value2" 
            } 
        ], 
    "runAsUser": "userName",
    "runAsPassword": "userPassword", 
    "timeoutInSeconds": 3600, 
    "outputBlobUri": "< SAS URI of a storage append blob with read, add, create, write access>", 
    "errorBlobUri": "< SAS URI of a storage append blob with read, add, create, write access >"  
    }
}

備註

  • 您可以提供內嵌指令碼、指令碼 URI 或內建指令碼命令識別碼作為輸入來源。 指令碼 URI 是具有讀取存取權或公用 URI 的儲存體 Blob SAS URI。
  • 一個命令執行只支援一種類型的來源輸入。
  • 「執行命令」支援使用 outputBlobUri 和 errorBlobUri 參數將輸出與錯誤寫入儲存體 Blob,這可用來儲存大型指令碼輸出。 請使用具有讀取、新增、建立、寫入存取權的儲存體附加 Blob SAS URI。 Blob 的類型應為 AppendBlob。 若是其他類型,寫入指令碼輸出或錯誤 Blob 的作業將會失敗。 已存在的 Blob 將會被覆寫。 如果不存在,系統會加以建立。

列出 VM 上執行命令的執行中執行個體

GET /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/<vmName>/runcommands?api-version=2019-12-01

取得特定執行命令部署的輸出詳細資料

GET /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/<vmName>/runcommands/<runCommandName>?$expand=instanceView&api-version=2019-12-01 

刪除特定的「執行命令」部署

刪除「執行命令」的執行個體

DELETE /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/<vmName>/runcommands/<runCommandName>?api-version=2019-12-01 

以排序次序部署指令碼

若要循序部署指令碼,請使用部署範本,指定循序指令碼之間的 dependsOn 關聯性。

{ 
    "type":"Microsoft.Compute/virtualMachines/runCommands",
    "name":"secondRunCommand",
    "apiVersion":"2019-12-01",
    "location":"[parameters('location')]",
    "dependsOn":<full resourceID of the previous other Run Command>,
    "properties":{
        "source":{
            "script":"echo Hello World!" 
        },
        "timeoutInSeconds":60
    }
}

循序執行多個執行命令

根據預設,如果您使用部署範本部署多個 RunCommand 資源,這些資源將會在 VM 上同時執行。 如果您的指令碼有相關性和慣用的執行順序,您可以使用 dependsOn 屬性來依序執行。

在此範例中,secondRunCommand 會在 firstRunCommand 之後執行。

{
   "$schema":"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
   "contentVersion":"1.0.0.0",
   "resources":[
      {
         "type":"Microsoft.Compute/virtualMachines/runCommands",
         "name":"[concat(parameters('vmName'),'/firstRunCommand')]",
         "apiVersion":"2019-12-01",
         "location":"[parameters('location')]",
         "dependsOn":[
            "[concat('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
         ],
         "properties":{
            "source":{
               "script":"echo First: Hello World!"
            },
            "parameters":[
               {
                  "name":"param1",
                  "value":"value1"
               },
               {
                  "name":"param2",
                  "value":"value2"
               }
            ],
            "timeoutInSeconds":20
         }
      },
      {
         "type":"Microsoft.Compute/virtualMachines/runCommands",
         "name":"[concat(parameters('vmName'),'/secondRunCommand')]",
         "apiVersion":"2019-12-01",
         "location":"[parameters('location')]",
         "dependsOn":[
            "[concat('Microsoft.Compute/virtualMachines/', parameters('vmName'),'runcommands/firstRunCommand')]"
         ],
         "properties":{
            "source":{
               "scriptUri":"http://github.com/myscript.ps1"
            },
            "timeoutInSeconds":60
         }
      }
   ]
}

下一步

請參閱在 Linux VM 中執行指令碼,了解如何以其他方式從遠端在 VM 中執行指令碼和命令。