After you deploy a Virtual Machine you typically need to make some changes before it’s ready to use. This is something you can do manually or you could use Remote PowerShell to automate the configuration of your VM after deployment for example.
But now there’s a third alternative available allowing you customize your VM: the CustomScript extension. This CustomScript extension is executed by the VM Agent (which was announced a few weeks ago by Scott Guthrie) and it’s very straightforward: you specify which files it needs to download from your storage account and which file it needs to execute. You can even specify arguments that need to be passed to the script. The only requirement is that you execute a .ps1 file.
Running a custom script
In this post I’ll run a script that creates a directory somewhere on the machine. This script accepts the name of the directory to create as argument and simply creates the directory:
param($dirName) mkdir $dirName
So I saved this file as createdir.ps1 and uploaded it to my storage account in the scripts container. I also changed the public access level of my container to Blob, which allows anyone to download the files in the container if they know the exact url. The CustomScript extension also allows you to set the storage account name and key, but changing the public access level is fine for me (you can do this with most storage tools like CloudXplorer, Cloud Storage Studio, …).
Now I simply upload my script to this container and configure the extension:
- The -FileUri argument allows me to specify the files that need to be downloaded. In my case this is the createdir.ps1 file
- The -Run argument allows me to choose which script needs to be executed.
- The -Argument is optional and allows my to specify and arguments I want to pass to the script being executed. In this example this is where I specify the name of the directory that needs to be created and where it should be created.
$context = Get-AzureVM -ServiceName mycloudservice -Name myvm Set-AzureVMCustomScriptExtension -VM $context.VM -FileUri 'http://azurepasseastus.blob.core.windows.net/scripts/createdir.ps1' -Run 'createdir.ps1' -Argument 'c:\hello_from_customscriptextension' Update-AzureVM -VM $context.VM -ServiceName mycloudsservice -Name myvm
After a few seconds the VM has been updated and the VM agent will start executing the extension.
You can follow everything that happens in the logfile of the CustomScript extension: C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\1.0.1\CustomScriptHandler.log. Here is what happened when I executed my script:
2014-04-09T00:25:37.7453299Z [Info]: Starting IaaS ScriptHandler Extension v1
2014-04-09T00:25:37.7453299Z [Info]: HandlerEnvironment = Version: 1, HandlerEnvironment: [LogFolder: "C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\1.0.1", ConfigFolder: "C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.0.1\RuntimeSettings", StatusFolder: "C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.0.1\Status", HeartbeatFile: "C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.0.1\Status\HeartBeat.Json"]
2014-04-09T00:25:37.7453299Z [Info]: Enabling Handler
2014-04-09T00:25:37.7453299Z [Info]: Handler successfully enabled
2014-04-09T00:25:37.7609538Z [Info]: Loading configuration for sequence number 5
2014-04-09T00:25:37.7765809Z [Info]: HandlerSettings = ProtectedSettingsCertThumbprint: , ProtectedSettings: {}, PublicSettings: {FileUris: [http://azurepasseastus.blob.core.windows.net/scripts/createdir.ps1], CommandToExecute: powershell -ExecutionPolicy Unrestricted -file createdir.ps1 c:\hello_from_customscriptextension}
2014-04-09T00:25:37.8390838Z [Info]: Downloading files specified in configuration…
2014-04-09T00:25:37.8703328Z [Info]: DownloadFiles: fileUri = “http://azurepasseastus.blob.core.windows.net/scripts/createdir.ps1“, baseUri = “http://azurepasseastus.blob.core.windows.net/”
2014-04-09T00:25:38.2140982Z [Info]: Files downloaded. Asynchronously executing command: ‘powershell -ExecutionPolicy Unrestricted -file createdir.ps1 c:\hello_from_customscriptextension‘
2014-04-09T00:25:38.2140982Z [Info]: Command execution task started. Awaiting completion…
2014-04-09T00:25:39.4628543Z [Info]: Command execution finished. Command exited with code: 0
And here’s the directory that was created by my script:
Enjoy!