You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:.NET 8 C#函数应用如何用Azure ARM SDK远程执行Azure VM上的EXE?

问题

我需要编写一个.NET 8 C#函数应用,用于远程运行Azure虚拟机(VM)上的EXE文件。尝试使用Azure.ResourceManager SDK实现,但无法正确创建RunCommandInput实例。

目前的代码如下:

public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    _logger.LogInformation("Invoking remote executable on Windows VM using RunCommand");

    // Azure authentication and setup
    string tenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
    string clientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
    string clientSecret = Environment.GetEnvironmentVariable("AZURE_CLIENT_SECRET");
    string subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
    string resourceGroupName = "YOUR_RESOURCE_GROUP";
    string vmName = "YOUR_VM_NAME";

    // Use DefaultAzureCredential for authentication
    var credential = new DefaultAzureCredential();

    // Initialize Azure resource manager client
    var armClient = new ArmClient(credential, subscriptionId);

    // Get the specific VM resource
    var subscription = armClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
    ResourceGroupResource resourceGroup = subscription.GetResourceGroup(resourceGroupName);
    VirtualMachineResource vmResource = resourceGroup.GetVirtualMachine(vmName);

    try
    {
        // Use Azure Compute's RunCommand to execute a PowerShell script on the VM
        var runCommandInput = new RunCommandInput("RunPowerShellScript");
        //{
        //    Script = new List<string> { commandToExecute },
        //    Parameters = new List<RunCommandInputParameter> {}
        //};

        _logger.LogInformation("Running command on VM...");

        // Execute the command
        var runCommandResult = await vmResource.RunCommandAsync(WaitUntil.Completed, runCommandInput);

        // Log the result
        //_logger.LogInformation($"Command executed successfully. Status: {runCommandResult.Value.Status}");
    }
    catch (RequestFailedException ex)
    {
        _logger.LogError($"Failed to execute command on VM: {ex.Message}");
    }

    return new OkObjectResult("OK");
}

现在RunCommandInput类的Parameters和Script字段均为只读,无法直接赋值,也未找到可设置这些字段的辅助/扩展方法。该类有一个可设置这些字段的构造函数,但它是内部构造函数,无法调用。


解决方案

1. 方案可行性确认

完全可行,Azure.ResourceManager.Compute SDK支持通过RunCommand功能远程在VM上执行PowerShell脚本(或其他类型命令),进而调用EXE文件。

2. 正确创建RunCommandInput实例的方法

RunCommandInput是SDK生成的模型类,官方提供了静态创建方法RunCommandInput.CreateRunCommandInput来实例化,该方法支持传入脚本内容和参数。

3. 修改后的完整代码

public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    _logger.LogInformation("Invoking remote executable on Windows VM using RunCommand");

    // Azure authentication and setup
    string tenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
    string clientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
    string clientSecret = Environment.GetEnvironmentVariable("AZURE_CLIENT_SECRET");
    string subscriptionId = Environment.GetEnvironmentVariable("AZURE_SUBSCRIPTION_ID");
    string resourceGroupName = "YOUR_RESOURCE_GROUP";
    string vmName = "YOUR_VM_NAME";
    // 替换为你的EXE路径和命令
    string exeCommand = @"& ""C:\path\to\your\application.exe""";

    // Use DefaultAzureCredential for authentication
    var credential = new DefaultAzureCredential();

    // Initialize Azure resource manager client
    var armClient = new ArmClient(credential, subscriptionId);

    // Get the specific VM resource
    var subscription = armClient.GetSubscriptionResource(new ResourceIdentifier($"/subscriptions/{subscriptionId}"));
    ResourceGroupResource resourceGroup = await subscription.GetResourceGroupAsync(resourceGroupName);
    VirtualMachineResource vmResource = await resourceGroup.GetVirtualMachineAsync(vmName);

    try
    {
        // 使用静态创建方法构建RunCommandInput
        var runCommandInput = RunCommandInput.CreateRunCommandInput(
            commandId: "RunPowerShellScript",
            script: new List<string> { exeCommand },
            parameters: new List<RunCommandInputParameter>()
        );

        _logger.LogInformation("Running command on VM...");

        // Execute the command
        var runCommandResult = await vmResource.RunCommandAsync(WaitUntil.Completed, runCommandInput);

        // 打印命令执行的详细输出
        var resultValue = runCommandResult.Value;
        _logger.LogInformation($"Command execution status: {resultValue.Status}");
        foreach (var output in resultValue.Value.Message)
        {
            _logger.LogInformation($"Output: {output}");
        }
    }
    catch (RequestFailedException ex)
    {
        _logger.LogError($"Failed to execute command on VM: {ex.Message}, Error code: {ex.Status}");
    }

    return new OkObjectResult("Command execution initiated");
}

4. 关键注意事项

  • 权限配置:用于认证的服务主体或系统分配身份必须拥有对目标VM的Microsoft.Compute/virtualMachines/runCommand/action权限(可通过"虚拟机参与者"或自定义角色配置)。
  • VM网络要求:VM必须能与Azure服务通信(无需公网IP,但需启用Azure实例元数据服务)。
  • EXE路径处理:PowerShell中执行EXE需注意路径包含空格时的引号转义,示例中使用& ""路径""的格式避免解析错误。
  • 结果处理:RunCommandResult包含命令执行的状态和输出日志,建议捕获并记录这些信息用于调试。

内容的提问来源于stack exchange,提问作者Dhawal Dhingra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:55:54