使用托管运行命令在 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-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 "chinanorth2" -RunCommandName "RunCommandName" -SourceScript "echo Hello World!"

使用 SourceScriptUri 参数在 VM 上执行脚本

可选参数为 OutputBlobUriErrorBlobUri

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 上创建或更新运行命令

使用包含 PowerShell 脚本的存储 blob 的 SAS URL 在 Windows VM 上创建或更新运行命令。 SourceScriptUri 可以是存储 blob 的完整 SAS URL 或公共 URL。

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location chinanorth2 -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 chinanorth2 -ScriptLocalPath "C:\MyScriptsDir\MyScript.ps1"

使用 SourceScript(脚本文本)在 VM 上创建或更新运行命令

在 VM 上创建或更新运行命令,将脚本内容直接传递到 -SourceScript 参数。 使用 ; 分隔多个命令

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

使用 SourceCommandId 在 VM 上创建或更新运行命令

使用已存在的 commandId 在 VM 上创建或更新运行命令。 可以使用 Get-AzVMRunCommandDocument 检索可用的 commandId。

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location chinanorth2 -SourceCommandId DisableWindowsUpdate

使用 OutputBlobUri 和 ErrorBlobUri 在 VM 上创建或更新运行命令,将标准输出和标准错误消息流式传输到输出和错误追加 blob

在 VM 上创建或更新运行命令,并将标准输出和标准错误消息流式传输到输出和错误追加 blob。

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVML -RunCommandName MyRunCommand3 -Location chinanorth2 -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 上创建或更新运行命令

使用 RunAsUserRunAsPassword 参数以其他用户的身份在 VM 上创建或更新运行命令。 若要使运行方式正常工作,请与 VM 的管理员联系,并确保在 VM 上添加用户、用户有权访问由运行命令访问的资源(目录、文件、网络等),并且(在 Windows VM 的情况下)VM 上正在运行“辅助登录”服务。

Set-AzVMRunCommand -ResourceGroupName MyRG0 -VMName MyVMEE -RunCommandName MyRunCommand -Location chinanorth2 -ScriptLocalPath "C:\MyScriptsDir\MyScript.ps1" -RunAsUser myusername -RunAsPassword mypassword

使用 SourceScriptUri(存储 blob SAS URL)在虚拟机规模集资源上创建或更新运行命令

使用包含 PowerShell 脚本的存储 blob 的 SAS URL 在 Windows 虚拟机规模集资源上创建或更新运行命令。

Set-AzVmssVMRunCommand -ResourceGroupName MyRG0 -VMScaleSetName MyVMSS -InstanceId 0 -RunCommandName MyRunCommand -Location chinanorth2 -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 令牌。

使用 Parameter 和 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 chinanorth2 -SourceScriptUri <SourceScriptUri> -Parameter $PublicParametersArray -ProtectedParameter $ProtectedParametersArray
  • Windows:Parameter 和 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 或内置脚本命令 ID 作为输入源。 脚本 URI 是具有读取访问权限或公共 URI 的存储 Blob SAS URI。
  • 一个命令执行仅支持一种类型的源输入。
  • 从 API 版本 2023-03-01 开始,可以将 treatFailureAsDeploymentFailure 属性设置为 true,使部署在脚本失败时失败。 如果设置为 false,则 ProvisioningState 将仅反映 run 命令是否由扩展平台运行。 它不会指示脚本在脚本失败时是否失败。
  • 运行命令支持使用 outputBlobUri 和 errorBlobUri 参数将输出和错误写入存储 Blob,这些参数可用于存储大型脚本输出。 使用具有读取、添加、创建、写入访问权限的存储追加 Blob 的 SAS URI。 Blob 的类型应为 AppendBlob。 否则,编写脚本输出或错误 Blob 会失败。 如果 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
         }
      }
   ]
}

后续步骤

若要了解在 VM 中远程运行脚本和命令的其他方法,请参阅在 Windows VM 中运行脚本