Azure VM Extensions: Part 2 CustomScriptExtension

This blog post covers some of the battles I have had trying to install some software onto a VM within Azure. There are many ways to go about this and at the end of the day, yeah you live to fight another day.

High level requirements:

1 – Install Zabbix Agent (which is a windows service) onto the same VM and ensure the service starts correctly.

As like most things in life there is more than one way to do something, I could have used RunCommands I could add onto the DSC and added this step into part 1 etc. etc.

I went with using an Azure CustomScriptExtension, maybe not the best option, who knows, but here is how to get this working.

module virtualMachineName_ZabixxInstaller './modules/Microsoft.Compute/virtualMachines/extensions/deploy.bicep' = {
  scope: resourceGroup(multiTenantResourceGroupName)
  name: 'ZabixxInstaller'
  params: {
    enableAutomaticUpgrade: false
    name: 'ZabixxInstaller'
    publisher: 'Microsoft.Compute'
    type: 'CustomScriptExtension'
    typeHandlerVersion: '1.10'
    virtualMachineName: virtualMachineNameBackend
    location: location
    autoUpgradeMinorVersion: true
    settings: {
       fileUris: [ 
    protectedSettings: {
      commandToExecute: 'powershell.exe -ExecutionPolicy Unrestricted -File InstallZabbixAgentGS.ps1'
      managedIdentity: {}
  dependsOn: [

So lets break this code down, firstly I make use of already written Azure Bicep Resource Modules which you can grab here :-

I’m also using version 1.10 of this extension so make sure to watch out for that.

The fileUris are pointing to a storage account that has public access DISABLED, enabling public access is not what you want, notice the part at the end which is a SAS Token, I tried to get this working using a Managed Identity and gave up as running out of time, the docs say you can use a Managed Identity and maybe I will go back and try this now that I have more time, then update this blog post.

“If I generate a new SAS each time you deploy based on deployment time, it will re-run the Script extensions every time, since that SAS value changes. If you move to Managed Identity, the script extension does not have to process when you redeploy, it will be skipped, since the configuration/settings didn’t change. If you want it to redeploy, with no changes, then you can change the value of the forceUpdateTag value.”

Huge shout out to he was helping me with this a LOT, and was super helpful, I owe it to him for helping me get this working and I owe it to him to go back and test it using Managed Identity.


So in summary I am generating a SAS token from the existing storage account like I do in Part 1 and then I pass that into fileUris so that I don’t run into permission issues.

Don’t forget to subscribe to my YouTube Channel. And my Newsletter