使用受控執行命令在 Windows VM 中執行指令碼
適用於:✔️ Windows VM ✔️ 彈性擴展集
重要
受控執行命令目前可用於 Azure CLI、PowerShell 和 API。 入口網站功能即將推出。
執行命令功能會使用虛擬機 (VM) 代理程式在 Azure Windows VM 內執行腳本。 您可以使用這些指令碼,進行一般電腦或應用程式管理。 這些指令碼可協助快速診斷和修復 VM 存取與網路問題,並讓 VM 恢復正常狀態。
更新的受控執行命令會使用相同的 VM 代理程式通道來執行指令碼,並透過原始動作導向執行命令提供下列增強功能:
- 透過 ARM 部署範本支援更新的執行命令
- 平行執行多個指令碼
- 循序執行指令碼
- 使用者指定的指令碼逾時
- 支援長時間執行 (小時/天) 的指令碼
- 以安全的方式傳遞秘密 (參數、密碼)
必要條件
支援 Windows OS
Windows OS | x64 |
---|---|
Windows 10 | 支援 |
Windows 11 | 支援 |
Windows Server 2008 SP2 | 支援 |
Windows Server 2008 R2 | 支援 |
Windows Server 2012 | 支援 |
Windows Server 2012 R2 | 支援 |
Windows Server 2016 | 支援 |
Windows Server 2016 Core | 支援 |
Windows Server 2019 | 支援 |
Windows Server 2019 Core | 支援 |
Windows Server 2022 | 支援 |
Windows Server 2022 Core | 支援 |
限制於執行命令的存取
列出執行命令或顯示命令詳細資料需要訂閱層級的 Microsoft.Compute/locations/runCommands/read
權限。 內建讀者角色和具有此權限的較高層級。
執行命令需要有 Microsoft.Compute/virtualMachines/runCommand/write
權限。 虛擬機器參與者角色和具有此權限的較高層級。
您可使用其中一個內建角色或建立自訂角色,以使用 [執行] 命令。
Azure CLI
下列範例使用 az vm run-command 在 Azure Windows VM 上執行 Shell 指令碼。
使用 VM 執行指令碼
此命令會將指令碼傳遞至 VM、執行,並傳回擷取的輸出。
az vm run-command create --name "myRunCommand" --vm-name "myVM" --resource-group "myRG" --script "Write-Host 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-AzVMRunCommand
或 Set-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 上執行指令碼
OutputBlobUri
和 ErrorBlobUri
是選擇性參數。
Set-AzVMRunCommand -ResourceGroupName "myRg" `
-VMName "myVM" `
-RunCommandName "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。
Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -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 權杖"
建立或更新「執行命令」之後,取得 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
:一般延伸模組佈建端對端的狀態 (延伸模組平台是否能夠觸發「執行命令」指令碼)。
使用 ScriptLocalPath (本機指令檔),在 VM 上建立或更新「執行命令」
在執行 Cmdlet 的用戶端電腦上使用本機指令檔,在 VM 上建立或更新「執行命令」。
Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location EastUS2EUAP -ScriptLocalPath "C:\MyScriptsDir\MyScript.ps1"
使用 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 DisableWindowsUpdate
使用 OutputBlobUri、ErrorBlobUri 在 VM 上建立或更新「執行命令」,以將標準輸出和標準錯誤訊息串流至輸出和錯誤附加 Blob
在 VM 上建立或更新「執行命令」,並將標準輸出和標準錯誤訊息串流至輸出和錯誤附加 Blob。
Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVML -RunCommandName MyRunCommand3 -Location EastUS2EUAP -ScriptLocalPath "C:\MyScriptsDir\MyScript.ps1" -OutputBlobUri <OutPutBlobUrI> -ErrorBlobUri "ErrorBlobUri
注意
輸出和錯誤 Blob 必須是 AppendBlob 類型,且其 SAS URL 必須提供 Blob 的讀取、附加、建立、寫入存取權。 SAS URL 的建議到期時間為 24 小時。 如果輸出或錯誤 Blob 不存在,則會建立 AppendBlob 類型的 Blob。 您可以使用 Blob 選項在 Azure 入口網站產生 SAS URL,或使用 New-AzStorageBlobSASToken
產生 SAS 權杖。
使用 RunAsUser 和 RunAsPassword 參數,以不同使用者身份在 VM 上建立或更新「執行命令」
使用 RunAsUser
和 RunAsPassword
參數,以不同使用者身份在 VM 上建立或更新「執行命令」。 若要讓 RunAs 正常運作,請連絡 VM 的管理員,並確定已在 VM 上新增使用者、使用者有權存取「執行命令」所存取的資源 (目錄、檔案、網路等),且如果是使用 Windows VM,也需確認 VM 上已執行「次要登入」服務。
Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location EastUS2EUAP -ScriptLocalPath "C:\MyScriptsDir\MyScript.ps1" -RunAsUser myusername -RunAsPassword mypassword
使用 SourceScriptUri (記憶體 Blob SAS URL),在虛擬機器擴展集資源上建立或更新「執行命令」
使用儲存體 Blob 的 SAS URL (包含 PowerShell 指令碼),在 Windows 虛擬機器擴展集資源上建立或更新「執行命令」。
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 執行個體上建立或更新「執行命令」
使用 ProtectedParameter 將任何敏感性輸入 (例如密碼、金鑰等) 傳遞至指令碼。
$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
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,並為執行命令執行個體指定唯一名稱。
PUT /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/<vmName>/runcommands/<runCommandName>?api-version=2023-03-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,
"treatFailureAsDeploymentFailure": true,
"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。
- 一個命令執行只支援一種類型的來源輸入。
- 從 API 2023-03-01 版開始,您可以將屬性
treatFailureAsDeploymentFailure
設定為 true, 這會在指令碼失敗時導致部署失敗。 如果設定為 false,ProvisioningState 只會反映「執行命令」是否由延伸模組平台執行。 若出現指令碼失敗,系統不會指出該指令碼是否失敗。 - 「執行命令」支援使用 outputBlobUri 和 errorBlobUri 參數將輸出與錯誤寫入儲存體 Blob,這可用來儲存大型指令碼輸出。 請使用具有讀取、新增、建立、寫入存取權的儲存體附加 Blob SAS URI。 Blob 的類型應為 AppendBlob。 若是其他類型,寫入指令碼輸出或錯誤 Blob 的作業將會失敗。 已存在的 Blob 將會被覆寫。 如果不存在,系統會加以建立。
列出 VM 上執行命令的執行中執行個體
GET /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/<vmName>/runcommands?api-version=2023-03-01
取得特定執行命令部署的輸出詳細資料
GET /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/<vmName>/runcommands/<runCommandName>?$expand=instanceView&api-version=2023-03-01
取消特定的執行命令部署
您也可以刪除執行命令的執行個體。
DELETE /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/<vmName>/runcommands/<runCommandName>?api-version=2023-03-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": "Write-Host 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":"2023-03-01",
"location":"[parameters('location')]",
"dependsOn":[
"[concat('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
],
"properties":{
"source":{
"script":"Write-Host 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
}
}
]
}
下一步
若要了解在虛擬機器中遠端執行指令碼和命令的其他方式,請參閱在 Windows 虛擬機器中執行指令碼。