1

I need to make changes to a Azure Resource Manager Virtual Machine that are not allowed on an existing machine, such as changing the availability group. So I have to delete and recreate the machine, attaching the existing disks, network adapters, etc. to the new VM. I have a PowerShell script to do this, but I'm running into a problem with Virtual Machine extensions.

Here's my code:

$NewVMConfig = New-AzureRmVMConfig -VMName $VM.Name -VMSize $VM.HardwareProfile.VmSize
$NewVMConfig = Set-AzureRmVMOSDisk -VM $NewVMConfig -Name $VM.StorageProfile.OSDisk.Name -VhdUri $VM.StorageProfile.OSDisk.VHD.Uri -CreateOption attach -Windows
foreach ($disk in $vm.StorageProfile.DataDisks) {
    $NewVMConfig = Add-AzureRmVMDataDisk -VM $NewVMConfig -Name $disk.Name -VhdUri $disk.Vhd.Uri -Caching $disk.Caching -DiskSizeInGB $disk.DiskSizeGB -CreateOption attach -Lun $disk.Lun
}
$NewVMConfig.AvailabilitySetReference = $VM.AvailabilitySetReference
$NewVMConfig.DiagnosticsProfile = $VM.DiagnosticsProfile
$NewVMConfig.Extensions = $VM.Extensions
$NewVMConfig.NetworkProfile = $VM.NetworkProfile
$location = $VM.Location
$resourceGroupName = $VM.ResourceGroupName

# Delete machine.  
Remove-AzureRmVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name

# Recreate machine
New-AzureRmVM -ResourceGroupName $resourceGroupName -Location $location -VM $NewVMConfig 

Notice the line:

$NewVMConfig.Extensions = $VM.Extensions

The script runs without any error, but the new VM doesn't have the same extensions as the original. The diagnostics extension is gone and it now has the BGInfo extension which wasn't on the original machine.

I can use the Remove-AzureRmVMExtension command to remove the BGInfo extension, but I have been unsuccessful at recreating the diagnostics extensions. I've tried both Set-AzureRmVMExtension and Set-AzureRmVMDiagnosticsExtension to no avail.

Scott
  • 4,458
  • 1
  • 19
  • 27

2 Answers2

1

Those VM extension commands do not support ARM yet. Hence, I suggest you to use ARM template instead. There is a quick-start template specifically for Windows VM with diagnostics extension on GitHub. You can download it and modify it to meet your needs, like specifying a VHD for your VM. And, use New-AzureRmResourceGroupDeployment to deploy your vm.

For your case, combining the above template with 201-specialized-vm-in-existing-vnet template would meet your needs.

Note: the 201-vm-diagnostics-extension-windows template deploys a Windows VM with diagnostics extension, while the 201-specialized-vm-in-existing-vnet template deploys a VM with existing VNet and VHD

For more information about this, see Create a Windows Virtual machine with monitoring and diagnostics using Azure Resource Manager Template.

For more information about authoring ARM template, see Authoring Azure Resource Manager templates.

For more information about deploying ARM template, see Deploy a Resource Group with Azure Resource Manager template.

Jack Zeng
  • 2,257
  • 12
  • 23
  • Thanks, I'll take a look at those templates and see if I can get it working that way. BTW, the VM extension commands I mentioned are the RM commands, and the Remove one worked, but the two Set ones didn't. – Scott Mar 04 '16 at 16:48
  • I am not sure how you make the `Remove-AzureVMExtension` works. It needs a "VM" parameter which is type "Microsoft.WindowsAzure.Commands.ServiceManagement.Model.IPersistentVM". It's specifically for ASM. I can't make it happen at my end. Could you share your script? – Jack Zeng Mar 07 '16 at 01:10
  • Oh, I see. I miss-understood you. I think you use `Remove-AzureRmVMExtension` to remove which is for ARM, while `Set-AzureVMExtension` and `Set-AzureVMDiagnosticsExtension` is for ASM. The ARM version of these two commands are not available yet. – Jack Zeng Mar 07 '16 at 01:20
0

Jack Zeng's answer with the virtual machine template showed me what was missing in my attempts to reconfigure the Azure diagnostics extension.

The key is that when you get a VM and look at the Extensions property (or the ExtensionsText property) it doesn't include the protected settings of the extension. (That's one way in which they are protected.) Thus you don't have all the information you need to recreate the extension. You have to rebuild the protected settings, which would vary from extension to extension, so you need to know what the specific extension requires. The virtual machine template to which Jack provide a link shows what information is needed for the protected settings of the Azure diagnostics extension, namely the storage account name, key, and endpoint.

Running the following code after recreating the virtual machine successfully reconfigured the diagnostics. In this code $VM is the original virtual machine object we got from calling Get-AzureRmVM before recreating the machine.

$diagnosticsExtension = $VM.Extensions | Where { $_.Name -eq 'Microsoft.Insights.VMDiagnosticsSettings' }

# The $VM.Extensions.Settings property does not correctly return the values of the different settings.
# Instead, use the $VM.ExtensionsText property to get the old settings.
$oldSettings = $VM.ExtensionsText | ConvertFrom-Json | Where { $_.Name -eq 'Microsoft.Insights.VMDiagnosticsSettings' } | foreach {$_.'properties.settings'}

# Need settings in a hash table.
$settings = @{
    xmlCfg = $oldSettings.xmlCfg; 
    StorageAccount = $oldSettings.StorageAccount
}

$storageAccounts = Get-AzureRmStorageAccount
$storageAccount = $storageAccounts | Where { $_.StorageAccountName -eq $settings.StorageAccount }
$storageAccountKeys = $storageAccount | Get-AzureRmStorageAccountKey

$protectedSettings = @{
    storageAccountName = $settings.StorageAccount;
    storageAccountKey = $storageAccountKeys.Key1;
    storageAccountEndPoint = "https://core.windows.net/"
}

Write-Host "Reconfiguring Azure diagnostics extension on $Name..."
$result = Set-AzureRmVMExtension -ResourceGroupName $newVM.ResourceGroupName -VMName $newVM.Name  -Name $diagnosticsExtension.name -Publisher $diagnosticsExtension.Publisher -ExtensionType $diagnosticsExtension.VirtualMachineExtensionType -TypeHandlerVersion $diagnosticsExtension.TypeHandlerVersion -Settings $settings -ProtectedSettings $protectedSettings -Location $diagnosticsExtension.Location

Note that I am running version 1.2.1 of the Azure PowerShell extensions. In this release, Set-AzureRmVMDiagnosticsExtension appears to be broken, so I did not use it.

Scott
  • 4,458
  • 1
  • 19
  • 27