How do I reconfigure the Azure diagnostics extension when recreating an Azure VM - powershell

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.

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'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.

Related

Azure Web App - Set Minimum version of TLS

Recently Azure added a feature in the UI to set a minimum TLS version per WebApp in the portal. I was wondering if anyone has found a way to set it through REST API or powershell. I have about 50 WebApps in each subscription and doing this manually would not be feasible.
Ive included a screenshot of the setting
enter image description here
CLI is actually available:
https://learn.microsoft.com/en-us/cli/azure/webapp/config?view=azure-cli-latest#az-webapp-config-set
PowerShell will be coming soon after a needed SDK update is complete.
This can be accomplished with PowerShell by calling the Set-AzureRMResource cmdlet with the relevant parameters. For your case:
# Iterate all sites and set the Minimum TLS version to 1.2 (SSL Settings)
Get-AzureRmResource -ResourceType Microsoft.Web/sites | ForEach-Object {
$params = #{
ApiVersion = '2018-02-01'
ResourceName = '{0}/web' -f $_.Name
ResourceGroupName = $_.ResourceGroupName
PropertyObject = #{ minTlsVersion = 1.2 }
ResourceType = 'Microsoft.Web/sites/config'
}
Set-AzureRmResource #params -Force
}
If you want to use PowerShell:
Set-AzWebApp -MinTlsVersion '1.2' -ResourceGroupName $ResourceGroupName -Name $webappName;

Configure Windows Defender for VMs in Scaleset

I have an Azure Scaleset with 5 VMs in it. When I deploy my app (service fabric app) to the scaleset, Windows Defender Real Time Protection is causing the CPU/Memory to max out. I think this is because there are no appropriate exclusions set up in the Windows Defender software.
Can anyone tell me if I can configure the exclusions on each VM without having to RDP on to all of the VMs?
Generally this is VM level config and so is usually managed via a custom VM image that already has things set up or via a VM extension that configures Defender as a part of the machine coming up (this is similar to #jason-ye-msft 's answer). There's some similar guidance around setting up antimalware in a cluster here.
# Script to add Microsoft Antimalware extension to VM Scale Set(VMSS) and Service Fabric Cluster(in turn it used VMSS)
# Login to your Azure Resource Manager Account and select the Subscription to use
Login-AzureRmAccount
# Specify your subscription ID
#$subscriptionId="SUBSCRIPTION ID HERE"
Select-AzureRmSubscription -SubscriptionId $subscriptionId
# Specify location, resource group, and VM Scaleset for the extension
#$location = "LOCATION HERE" # eg., “West US or Southeast Asia” or “Central US”
#$resourceGroupName = "RESOURCE GROUP NAME HERE"
#$vmScaleSetName = "YOUR VM SCALE SET NAME"
# Configuration.JSON configuration file can be customized as per MSDN documentation: https://msdn.microsoft.com/en-us/library/dn771716.aspx
#$settingString = ‘{"AntimalwareEnabled": true}’;
# retrieve the most recent version number of the extension
$allVersions= (Get-AzureRmVMExtensionImage -Location $location -PublisherName “Microsoft.Azure.Security” -Type “IaaSAntimalware”).Version
$versionString = $allVersions[($allVersions.count)-1].Split(“.”)[0] + “.” + $allVersions[($allVersions.count)-1].Split(“.”)[1]
$VMSS = Get-AzureRmVmss -ResourceGroupName $resourceGroupName -VMScaleSetName $vmScaleSetName
Add-AzureRmVmssExtension -VirtualMachineScaleSet $VMSS -Name “IaaSAntimalware” -Publisher “Microsoft.Azure.Security” -Type “IaaSAntimalware” -TypeHandlerVersion $versionString
Update-AzureRmVmss -ResourceGroupName $resourceGroupName -Name $vmScaleSetName -VirtualMachineScaleSet $VMSS
The Service Fabric team does have guidance on how to configure your environment that includes the information about the exclusions you'd want to add. Those include:
Antivirus Excluded directories
Program Files\Microsoft Service Fabric
FabricDataRoot (from cluster configuration)
FabricLogRoot (from cluster configuration)
Antivirus Excluded processes
Fabric.exe
FabricHost.exe
FabricInstallerService.exe
FabricSetup.exe
FabricDeployer.exe
ImageBuilder.exe
FabricGateway.exe
FabricDCA.exe
FabricFAS.exe
FabricUOS.exe
FabricRM.exe
FileStoreService.exe
It's not clear if there's a good way to set up those exclusions at the same time that you're enabling antimalware scanning.
Can anyone tell me if I can configure the exclusions on each VM
without having to RDP on to all of the VMs?
Based on my knowledge, you should configure the exclusion for your image, then upload this image to Azure, then use this image to create new VMSS, in this way, after your increase your VMSS instance, newly created vmss instances will not be affected by Windows Defender software.

Installing Microsoft Anti-Malware or Symmantec endpoint protection on Service Fabric VM's

Anyone installed either Microsoft Malware Protection or Symmantec End Point Protection on the Service Fabric VM's. The Azure Security Center says it's possible, but I haven't been able to get it to work.
When you create the cluster, there is no extension option to add malware protection (that I could find). After you create the cluster, when you RDP into the servers, PowerShell Get-AzureRmVm can't find the ServiceName to use PowerShell to install the anti-malware. (I can get both those options to work on standalone VM's)
I'm thinking I'm missing something really simple, but I'm not seeing it.
Generally this is VM level config and so is usually managed via a custom VM image that already has things set up or via a VM extension. There's guidance around setting up antimalware in a cluster here.
# Script to add Microsoft Antimalware extension to VM Scale Set(VMSS) and Service Fabric Cluster(in turn it used VMSS)
# Login to your Azure Resource Manager Account and select the Subscription to use
Login-AzureRmAccount
# Specify your subscription ID
#$subscriptionId="SUBSCRIPTION ID HERE"
Select-AzureRmSubscription -SubscriptionId $subscriptionId
# Specify location, resource group, and VM Scaleset for the extension
#$location = "LOCATION HERE" # eg., “West US or Southeast Asia” or “Central US”
#$resourceGroupName = "RESOURCE GROUP NAME HERE"
#$vmScaleSetName = "YOUR VM SCALE SET NAME"
# Configuration.JSON configuration file can be customized as per MSDN documentation: https://msdn.microsoft.com/en-us/library/dn771716.aspx
#$settingString = ‘{"AntimalwareEnabled": true}’;
# retrieve the most recent version number of the extension
$allVersions= (Get-AzureRmVMExtensionImage -Location $location -PublisherName “Microsoft.Azure.Security” -Type “IaaSAntimalware”).Version
$versionString = $allVersions[($allVersions.count)-1].Split(“.”)[0] + “.” + $allVersions[($allVersions.count)-1].Split(“.”)[1]
$VMSS = Get-AzureRmVmss -ResourceGroupName $resourceGroupName -VMScaleSetName $vmScaleSetName
Add-AzureRmVmssExtension -VirtualMachineScaleSet $VMSS -Name “IaaSAntimalware” -Publisher “Microsoft.Azure.Security” -Type “IaaSAntimalware” -TypeHandlerVersion $versionString
Update-AzureRmVmss -ResourceGroupName $resourceGroupName -Name $vmScaleSetName -VirtualMachineScaleSet $VMSS
The Service Fabric team does have guidance on how to configure your environment that includes the information about the exclusions you'd want to add. Those include:
Antivirus Excluded directories
Program Files\Microsoft Service Fabric
FabricDataRoot (from cluster configuration)
FabricLogRoot (from cluster configuration)
Antivirus Excluded processes
Fabric.exe
FabricHost.exe
FabricInstallerService.exe
FabricSetup.exe
FabricDeployer.exe
ImageBuilder.exe
FabricGateway.exe
FabricDCA.exe
FabricFAS.exe
FabricUOS.exe
FabricRM.exe
FileStoreService.exe

Azure Web App Powershell Resource Manager Mode - Connection String Slot Setting

I'm adding Connection Strings to my Azure Web App using the AzureResourceManager mode in Powershell.
Using the Azure Resource Explorer I've found the correct Powershell to add a connection string to my web app
$PropertiesObject = #{
#Property = value;
MembershipConnection = #{
Value = "Server=tcp:members.database.windows.net,1433;Database=Membership;User ID=User#members;Password=passwordgoeshere;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
Type = "2";
}
}
New-AzureResource -PropertyObject $PropertiesObject -ResourceGroupName $resGroup -ResourceType Microsoft.Web/sites/config -ResourceName "$siteName/connectionstrings" -OutputObjectFormat New -ApiVersion "2015-08-01" -Force
However, I can't find a way of marking the Connection String as a Slot Setting, so that it doesn't move when switching between my Staging and Production deployment slots.
In the Portal, it's a simple checkbox alongside the connection string.
Thanks very much for any help!
You might already know that you can do this in the Azure Service Management Mode like this:
> Switch-AzureMode -Name AzureServiceManagement
> Set-AzureWebsite -Name myapp -SlotStickyConnectionStringNames #("my_db")
I appreciate, though, that your question is about using the Azure Resource Manager.

Change Azure Website platform from 32 to 64 bit with powershell

A website created with azure powershell defaults to 32bit platform
$prop = #{ "serverFarmId" = $plan.Id ; 'Sku' = 'Standard' }
New-AzureResource -ResourceName $webSiteName -Location $plan.Location -ResourceType 'Microsoft.Web/sites' -PropertyObject $prop -ResourceGroupName $resourceGroupName -Force }
I need to change it to 64bit. I think I can pass some parameter in the PropertyObject via New-AzureResource or Set-AzureResource, but I can't find the syntax.
How can I switch my website from 32 to 64 bit (or vice-versa)
I use the last version of Azure cmdLets to date (July 2015)
Bonus question :
The documentation is not explicit at all about possible values:
-PropertyObject Specifies the new property values. Enter a hash table of property names and values. The names and values are
case-sensitive.
Where can we found more info about these cmdLets? (yes, I tried google...)
To change your running website from 32-bit to 64-bit, you can use the following PowerShell cmdlets:
Get-AzureWebsite "websitenamegoeshere"
Look at the Use32BitWorkerProcess value...this would allow you to look at the properties of the website to confirm the 32-bit process.
To change this value to false (and thus 64-bit) use the following:
Set-AzureWebsite "websitenamegoeshere" -Use32BitWorkerProcess $false
If you re-run the Get-AzureWebsite command, you should be able to confirm the value is now false. Additionally, if you check your website properties in the Azure portal, you should be able to confirm that it is now configured for 64-bit.
NOTE: You might need to refresh the browser with an F5 for cached values to be reloaded.
#Brian's solution works, but this one worked too.
It has the advantage in my case of setting "AlwaysOn", Set-AzureWebsite does not have this parameter.
$r = Get-AzureResource -ResourceName testskuws -ResourceType Microsoft.Web/sites -ResourceGroupName Default-Web-NorthCentralUS -OutputObjectFormat New
$r.Properties.SiteConfig = #{ 'AlwaysOn' = $true ; 'Use32BitWorkerProcess' = $false }
$r | Set-AzureResource -OutputObjectFormat New
With Azure cmdlets version of July 2015