Step by Step ARM Templates - Providing PowerShell Scripts to Run after VM deployment via ARM Template

@20aman    Oct 19, 2016

Index of all blogs in this Step by Step ARM Templates series is located here: Step by Step Azure Resource Manager (ARM) Templates - Index

By providing PowerShell Scripts to Run after VM deployment via ARM Template, you can accomplish various activities.

  • You can setup different features and roles on the VM.
  • You can setup web server.
  • You can setup SQL Database and configure it.
  • You can configure custom policies
  • And so on...

You first need to have PowerShell script files uploaded to a storage account. To do this you add an Extension resource (Microsoft.Compute/virtualMachines/extensions) nested inside a VM. This extension resource should be of type "CustomScriptExtension". You provide the URLs to the PowerShell scripts inside this custom script extension.


As part of the preparation process you need to:

  • Ensure that the PowerShell scripts are uploaded to the Storage Account and that you have the complete URL to the blob.
  • Or you can upload the scripts to the GitHub and get the Raw file URL
  • If there are more than one scripts then there should be one master script amongst all ps1 files which will internally invoke other files. This master file will be triggered via the template. Information of all file URLs will also be provided via the Template

Providing and configuring Scripts to Run After VM Deployment

Define the below resource to provide PowerShell scripts to be run after VM deployment:

   "type": "Microsoft.Compute/virtualMachines/extensions",
   "name": "MyCustomScriptExtension",
   "apiVersion": "2015-05-01-preview",
   "location": "[parameters('location')]",
   "dependsOn": [
   "properties": {
       "publisher": "Microsoft.Compute",
       "type": "CustomScriptExtension",
       "typeHandlerVersion": "1.7",
       "settings": {
           "fileUris": [

       "commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File start.ps1"

How it works:

  • Both the files i.e. start.ps1 and secondaryScript.ps1 are picked up from the storage account after VM deployment. Ensure to replace the URLs with your actual storage account blob URLs. You can add more files if needed.
  • The "start.ps1" is the main powerShell script which should be invoking the secondaryScript.ps1 internally
  • CommandToExecutre property is used to invoke the start.ps1 powerShell script on the deployed VM

Passing Parameters to the PowerShell Script dynamically

To pass the parameters to the PowerShell script use commandToExecute property.

One such example to pass the parameters is shown below:

"commandToExecute": "[concat('powershell.exe -ExecutionPolicy Unrestricted -File start.ps1', ' -domainName ', parameters('domainNameParameter')]"

Note the use of "concat" helper function to create the value of the "commandToExecute". Also note that there is starting and trailing space in the second argument of the concat i.e. " -domainName ".

The parameter "domainNameParameter" should already be defined in the template in the parameters section. If the value of parameter "domainNameParameter" is "" then the dynamically generated command will become:

powershell.exe -ExecutionPolicy Unrestricted -File start.ps1 -domainName

Securing the Access to the PowerShell Script File in Storage account

Let us assume you want to deploy Windows VM with Protected settings. Then use the below sample to provide the PowerShell files.

    "publisher": "Microsoft.Compute",
    "type": "CustomScriptExtension",
    "typeHandlerVersion": "1.7",
    "settings": {
        "fileUris": [
            "http: //"
    "protectedSettings": {
        "commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -start.ps1",
        "storageAccountName": "yourStorageAccountName",
        "storageAccountKey": "yourStorageAccountKey"

Note the use of "protectedSettings" above. This time you also specify the Storage Account Name and the Storage Account Key.

You can also refer the official documentation here: Windows VM Custom Script extensions with Azure Resource Manager templates.

Comments powered by Disqus