Enabling WinRM Using Custom Script Extensions in Azure ARM

When provisioning vanilla Windows marketplace templates via CloudBolt, WinRM and the firewall policy prevent remote execution by default. This presents a 'chicken and the egg' scenario where in order to enable remote scripting against the VM, it must first be accessed via RDP and configured. When deploying VMs at scale, this solution becomes untenable.

In order to workaround this issue, a Cloudbolt plugin can install a VM Extension, which runs a Powershell script on Azure VMs using the Azure VM Agent. Azure supports a number of VM Extensions which can be launched at provision time or after the VM is running, enabling anything from launching a simple Powershell script on the VM to installing antivirus software. More info about VM extensions can be found here.

In order to enable WinRM on a newly provisioned VM in CloudBolt, we can use a Post Provision hook to install a VM Extension. Although a different Powershell script might be required for any specific use case, the commands we'll use are stored in github here and are as follows:

winrm quickconfig -q

winrm set winrm/config/service '@{AllowUnencrypted="true"}'

winrm set winrm/config/service/auth '@{Basic="true"}'

Start-Service WinRM set-service WinRM -StartupType Automatic

Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled false

Simply put, the above powershell commands enable WinRM, ensures it is started automatically and completely disables the Windows firewall. However, you may use any Powershell script you wish as long as it enables the same configuration. Additionally, you may decide to store your script in Azure storage. For more information about uploading your script to an Azure storage account, as opposed to github, see here.

During Step 3 (Settings: Configure optional features) of creating a new VM in the Azure portal, the 'Extensions' feature allows for the addition of an extension to the VM. See below:


For this example, we'll leverage the 'Custom Script Extension' extension published by Microsoft. When selected in the portal it will prompt for a file to upload, but we'll be calling a script stored in github and installing via a CloudBolt plugin (attached to this KB article).

The attached python script should be uploaded as a CloudBolt plugin under Server Actions and tested (as a Server Action) before including it as a Post Provisioning (trigger point 10) Orchestration Action. If deployed as a Post Provisioning Orchestration action, it should occur first in the list if any subsequent scripts require remote execution.

Once imported into your environment, ensure that all Action Input types are set to 'String', except the 'Settings' Action Input which should be set to type: 'Code'. Also ensure that its Resource Technology is set specifically to Azure ARM and that is it Shared:


Now set some defaults on the Action Inputs (Admin -> Server Actions, filter down to your Action:

Extension Name: CustomScriptExtension
Protected Settings: (Leave this blank)
Publisher: Microsoft.Compute
Settings: {"fileUris": ["https://raw.githubusercontent.com/CloudBoltSoftware/cloudbolt-forge/master/actions/remote_scripts/enable_winRM.ps1"],"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File enable_winRM.ps1"}
Version: 1.9

See below:


Now test this Server Action against an applicable server under CloudBolt management:


To verify that the plugin properly installs the VM extension, check the 'Extensions' section in the Azure portal for that particular VM. The Status column should say 'Provisioning succeeded':



You can get more details by double-clicking the Extension:


Note that the installation process is asynchronous. The plugin includes a four minute (240 second) sleep timer in order to allow the installation to complete. This is important to remember when deploying this plugin as an Orchestration Action which might include remote scripts after it that depend on remote execution. The sleep timer can be increased or reduced depending on your use case.

If the VM extension is installed successfully via the plugin, Ad-Hoc scripts as well as Remote Execution via CloudBolt will be enabled on the VM.



Have more questions? Submit a request


  • 1
    Thomas Mukunnemkeril

    The python script didn't work for me initially.  I'd get an error about 1 positional parameter expected, but 2 positional found and 5 additional keyword (not sure exact wording anymore)

    Changing the script at line 43, instead of location, I specified location=location and the script started working:

    on line 43:
     extension_parameters = VirtualMachineExtension(                                         
  • 0
    Aaron Jablonowski

    Thanks for that feedback, Thomas- I've updated the uploaded plugin. 

Please sign in to leave a comment.