Running scripts on an Azure ARM VM with CustomScriptExtensions and PowerShell

There are certain situations with an Azure VM where running scripts through PowerShell remoting or logging on to the machine locally is not desirable. In these cases it’s great to use CustomScriptExtensions. This really shines when performing new deployments, right before any form of access rules and methods to access the VM have been configured.

The real beauty with it is that you can run more than one script. If you provide a “main” runner script that calls other scripts, you will be able to use methods and functions that are dependent on each other. I have yet to try to provide modules this way, but I reckon it can be done by initiating downloads and directory creation from the main runner itself. I will research this and update/write a new post on how to use custom modules with CustomScriptExtensions if applicable.


In this example I will provide a script that imports functions from another scripts. It runs the functions and put the output to a file. Notice that if you want to send an array as a parameter value you’ll need to specify these as a comma separated string. Like so: -ParamArray 'val1,val2,val3'. Notice that this is not the ordinary –ParamArray 'val1','val2','val3'.

So if one of your functions takes an array, you’ll need to create one in the “main” script from the comma-separated string. Like so $params = $ParamArray.Split(',').

Below are example scripts (main.ps1 and functions.ps1).

Powershell Examples

To make use of these, execute the following command(s) in PowerShell.

Of course, these are just very basic example. But I think I made my point quite clear.

The things to think about when creating a main runner script, is that it will need to handle the parameters and decide on how to format them to the functions within. Mainly when using arrays. Use ordinary comma separated string TO the main runner, and in the main runner create an array from it and use in your functions. It’s also important that you specify your runner file (in the example it’s main.ps1) in the -Run parameter.

Additional information can be found on: Microsofts official documentation