Powershell code executed every time after allocating an Azure VM

258 views Asked by At

i'm getting crazy with Azure APIS :-D we noticed that each PowerShell script "injected" via our internal application built using Azure Management Fluent API 1.34.0 is re-executed every time I allocate the VM. The script is stored in a storage account and the application is taking care to download and execute it inside the VM. The file is downloaded again and again inside the folder "C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\1.1.5\Downloads". What am i doing wrong?

2

There are 2 answers

0
mdurini On

this is the code

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));
}
0
mdurini On

Just an update: after investigating with the Azure support team, I spoke with a Microsoft Senior Engineer and he discovered a bug in the Azure backend

Root cause is that VM has been previously used to call RunCommand API and this remains in the VM model we store internally. This model does not change when you swap the disk and the VM configuration stull contains (a hidden for you) RunCommandWindows extension which gets executed on the new OSDisk because the flag if previously executed is stored in the registry (which is gone when you swap the disk). We agree that fix is needed for your scenario that will cleanup the runcommand from the VM model as well when OSdisk get swapped. Until we prepare and deploy the fix (usually within 1 month cycle) I can suggest a mitigation that you can apply just before you swap the disks. You can remove the run command extension from the VM model by calling a special run command with commandId = RemoveRunCommandWindowsExtension It is not available on the portal but you can use REST, CLI, Powershell or .Net API. For example: 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 This will delete the extension and after you swap the disk it will not be installed and run again.

I hope that this workaround will help anybody else until the fix will be applied in the backed.