0

我对 Azure APIS 越来越疯狂:-D 我们注意到,每次我分配 VM 时,都会重新执行通过使用 Azure Management Fluent API 1.34.0 构建的内部应用程序“注入”的每个 PowerShell 脚本。该脚本存储在一个存储帐户中,应用程序会小心地在 VM 中下载并执行它。该文件在“C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.5\Downloads”文件夹中一次又一次地下载。我究竟做错了什么?

4

2 回答 2

0

只是更新:在与 Azure 支持团队进行调查后,我与一位 Microsoft 高级工程师交谈,他发现 Azure 后端存在错误

根本原因是 VM 之前已用于调用 RunCommand API,而这仍保留在我们内部存储的 VM 模型中。当您交换磁盘时,此模型不会更改,并且 VM 配置文件包含(对您隐藏)RunCommandWindows 扩展,该扩展在新的 OSDisk 上执行,因为如果先前执行的标志存储在注册表中(当您交换盘)。我们同意您的方案需要修复,以便在交换 OSdisk 时清除 VM 模型中的运行命令。在我们准备和部署修复程序之前(通常在 1 个月内),我可以建议您在交换磁盘之前应用一种缓解措施。您可以通过调用带有 commandId = RemoveRunCommandWindowsExtension 的特殊运行命令从 VM 模型中删除运行命令扩展。它在门户上不可用,但您可以使用 REST、CLI、Powershell 或 .Net API。例如: Invoke-AzureRmVMRunCommand -ResourceGroupName 'rgname' -Name 'vmname' -CommandId 'RemoveRunCommandWindowsExtension' Powershell Invoke-AzureRmVMRunCommand -ResourceGroupName 'rgname' -Name 'vmname' -CommandId 'RemoveRunCommandWindowsExtension' CLI az vm run-command invoke -g MyResourceGroup -n MyVM --command-id RemoveRunCommandWindowsExtension 这将删除扩展,并且在您交换磁盘后它将不再安装和运行。

我希望此解决方法将对其他人有所帮助,直到将修复程序应用到支持中。

于 2020-12-07T07:57:13.723 回答
0

这是代码

public async Task<string> RunBasePowershellAsync(string virtualMachineName, string file, Dictionary<string, string> psParams = null)
{
    if (psParams == null)
    {
        psParams = new Dictionary<string, string>();
    }
 
    var vm = _azure.VirtualMachines.List().SingleOrDefault(v => v.Name == virtualMachineName);
    if (vm == null)
    {
        throw new BoardCloudServiceException($"Virtual Machine {vm} not found!");
    }
 
    var httpRequest = (HttpWebRequest)WebRequest.Create(file);
    httpRequest.Method = WebRequestMethods.Http.Get;
 
    var httpResponse = (HttpWebResponse)httpRequest.GetResponse();
 
    var encoding = string.IsNullOrEmpty(httpResponse.CharacterSet)
        ? Encoding.UTF8
        : Encoding.GetEncoding(httpResponse.CharacterSet);
 
    using var stream = httpResponse.GetResponseStream();
    using var reader = new StreamReader(stream, encoding);
    var responseString = reader.ReadToEnd();
    var lines = responseString.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
    var result = await vm.RunPowerShellScriptAsync(lines, psParams.Select(p => new RunCommandInputParameter(p.Key, p.Value)).ToList());
 
    return string.Join("", result.Value.Select(v => v.Message));
}
于 2020-11-30T12:58:15.260 回答