Can We Install Custom Software on Windows Azure?

Recently, a few people asked me similar questions:

Can we install custom software on Windows Azure?

In a nutshell, I will yes, it is possible! Next, the question:

How to do it? How complex it is?

Before answering those question, I’ll start this discussion with some basic concept first.

Start with Basic Concept First

Cloud Design Philosophy: Scaling for capacity and redundancy

Windows Azure is the cloud environment to enable customer to elastically scale in and out where necessary.

  • Scale out means to increase # of VM so that can process / compute more (of course you may more).
  • Scale in means to decrease # of VM because we may not need too many VM (of course you pay less).

This might lead to the rule-of-thumb:

Stateless Internally, State-full with External Durable Storage

Local Storage Inside VM Instance

When specify the VM Size of our Windows Azure service, the VM eventually will come with the Compute power and internal local storage. The internal local storage itself is actually the local virtual hard-disk which size varies from 20 GB (Extra Small) – 2 TB (Extra Large), mounted as Drive C:.

Please refer to my previous post of A Deep Look Inside Windows Azure VM for more detail.


Although there’s some dedicated local hard-disk space inside each VM, there are some caveats:

1. Not Persistence

Local Storage is considered not-persistence. Meaning the data stored inside the local storage may be gone when scenario such as:

  • That’s the node that deleted when we scale-in (# of instances is reduced)
  • Due to hardware failure, Windows Azure will spin up the VM on another node for us

2. Not Centralized

If we store data inside the VM, the data could only be accessed by that VM instance, not the rest of the VM. This obviously doesn’t make sense when we have many VM instance running on.

When it is useful?

A few useful scenario of using Local Storage:

1. Storage Temporary Data

Local Storage is very useful when storing temporary data which doesn’t require any persistency guarantee.

2. A cache copy of Windows Azure Drive

Windows Azure Drive provides an optional local on-disk cache of the drive’s data. Employing the cache is useful to reduce the transaction cost of accessing the blob service.

Scalable, Persistence Storage – SQL Azure / Windows Azure Storage

We could achieve durability, scalability, and persistency when using SQL Azure or Windows Azure Storage. By doing so, regardless how many VM instances we have, they are able to access the centralized storage appropriately.

Having understood the basic concept, here’re a few techniques that may help you install custom software on Windows Azure.

Start-up Task

Since SDK 1.3, Microsoft introduced a concept called Start-up Task. The idea of the start-up task is enable us to run a set of command script or PowerShell script before our instance starts. Typically, you can configuring anything with start-up task as long as it must be scripted.

Here’re some example of what can we do with start-up task:

  • Downloading from a link
  • Install some custom software
  • Configuring environment variable
  • Configuring registry
  • etc.

Although many tasks are achievable using start-up task. I will be focus on “Installing Software” in this case. In the example below, I use start-up task to download and install WinRar on Windows Azure.

How to?

1. Prepare your startup script.

Here is the example of startup.cmd file:

1: powershell -c “set-executionpolicy unrestricted”
2: powershell -c “(new-object””, ”winrar-x64-40b7.exe”)
3: winrar-x64-40b7.exe /s

  • The first line is to set the execution policy of my Powershell script to unrestricted.
  • The second line is to download a file from the given URL to local storage.
  • The third line is to run the installer “winrar-x64-40b7.exe” using silent mode (/s). (Note that each installer may have different silent mode installation parameter). By doing so, there’s no prompt screen which require us to click next – next – finish anymore.

I would recommend you to create the file using notepad or other ASCII editor, since textfile created by Visual Studio seems to have a byte order mark that will make it fail.

Please make sure that set “copy to output directory” to “copy always”, to ensure that the script will be included inside your package.


2. Modify your ServiceDefinition.csdef file by adding Startup – Task section.

service def

  • The commandLine attribute requires the path of our startup script
  • The executionContent attribute requires us to choose either:
    • elevated (which will run as admin-role) or
    • limited (non admin-role)
  • The taskType, with the following options
    • Simple [Default] – System waits for the task to exit before any other tasks are launched
    • Background – System does not wait for the task to exit
    • Foreground – Similar to background, except role is not restarted until all foreground tasks exit

Since the start-up task is scripted using elevated admin mode, it has enough right to write to local disk. Also, since the start-up task will be run every time the OS is provisioned, the state will be persistence at the time the installation is done.

I can tell that start-up task will be the preferable option (if possible).

The Catch

Any activity that could be scripted-out could run well using Start-up Task. But, what if not? Not all installer could be scripted out. Or some installer could be started up, but requires some manual step of UI-based configuration…

In this case, sadly to say that you can’t use Start-up Task Sad smile.

VM Role

VM Role is exactly created for the issue that couldn’t be addressed by Start-up Task. However, the name of the VM-Role is sometime misleading. Many people would think they can easily bring their entire VM and let it runs on the cloud directly and store whatever they want inside the VHD.

Well, this is true and false.

True that you will need to install the OS (and your intended software) by your own, configure necessary task (that you can’t scripted out), and bring your OS to the cloud.

False that the VHD itself is still non-persistence. Which means you still need to store your persistence data on Windows Azure Storage or SQL Azure. Remember, VM Role is not IAAS (Infrastructure-as-a-service).

VM Role LifeCycle


Here’s the lifecycle of the VM Role.

  • Build VM Image
    • Convert product DVD to a VHD, or use existing VHD
    • Prepare the VHD
  • Create Service
    • Create a service model with the above image.
  • Upload Image
    • Store VHD in Windows Azure blob storage
  • Deploy Service
    • Include in service model. Specify instance count.
    • Package as cspkg, upload cskpg.
  • Maintain Service
    • Remote Desktop
    • Reboot / Reimage
  • Upgrade Service
    • Repeat above steps, with a new OS image.

The Catch

1. With Web Role and Worker Role, Windows Azure will take care of the OS Update for you. Meaning that if there’s new patch of the OS, Windows Azure will automatically update our VM, which is the Guest OS. While with VM Role, you will have responsibility to manage by your own.

2. The supported OS of VM Role is only Windows Server 2008 R2. Other OS is definitely out of question.

2. At the time this article of written, VM Role is still at beta. Any thing may change when it is released. So, consider carefully if your company policy allows running beta / CTP software on the production.

Remote Desktop to Perform Manual Installation

This is actually not a good technique but I will include in this post as well since it maybe useful occasionally especially when doing testing or staging.

The idea of this technique is to enable remote desktop on our Windows Azure service and install the software using remote desktop.


The Catch

The big and fatal disadvantage of this technique: there is no guarantee that the changes or the installation that we’ve done will be persistence. Because, we are installing or making change the stateless VHD inside the VM. (Refer to the basic concept we’ve discussed above).

When it is helpful?

Nonetheless, a few advantage of this technique are:

1. Easy-to-do and Simple

We don’t have to bother about scripting out start-up task nor uploading the entire big VHD. Just Remote Desktop in and performing your installation as per normal condition.

2. Purely for testing purpose that can tolerate the catch

There may be some scenario that we’re just purely doing some testing and we can tolerate if the changes gone. If you can accept the catch, of course it’s fine for you.

But of course, word of warning: do not use this technique in PRODUCTION.


To conclude, I began with explaining the Windows Azure scaling concept and available storage. Subsequently, I discuss about three techniques (Start-up Task, VM Role, and Remote Desktop) with the explanation of how to achieve that, the advantages and the catch.

Hopefully this post will be helpful to you.

This entry was posted in Azure, Azure Development. Bookmark the permalink.

3 Responses to Can We Install Custom Software on Windows Azure?

  1. Aaron says:

    Say if we wanted to pass in instance-specific parameters to the installer of the custom software, like cloud_service_instance_name, is there any environment variables or other data source that can be retrieved?

    e.g. msiexec /qn /i installer.msi HOSTNAME=@SOME_HOSTNAME

  2. Aaron says:

    I am trying to apply this technique to a Node.js worker role cloud service, but it appears the automated powershell execution is failing to recognise the cmdlets?

    E:\approot>REM Install Notepad++

    E:\approot>powershell -c “set-executionpolicy unrestricted”
    “set-executionpolicy : The term '“set-executionpolicy' is not recognized
    as the name of a cmdlet, function, script file, or operable program. Check the
    spelling of the name, or if a path was included, verify that the path is
    correct and try again.
    At line:1 char:1
    + “set-executionpolicy unrestricted”
    + ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (“set-executionpolicy:String)
    [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    E:\approot>powershell -c (new-object””, ”npp.exe”)
    At line:1 char:48
    + (new-object” ...
    + ~
    Missing ')' in method call.
    At line:1 char:48
    + (new-object” ...
    Unexpected token '”
    Installer.exe”' in expression or statement.
    At line:1 char:125
    + ... nstaller.exe”, ”npp.exe”)
    + ~
    Missing argument in parameter list.
    At line:1 char:140
    + ... , ”npp.exe”)
    + ~
    Unexpected token ')' in expression or statement.
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordEx
    + FullyQualifiedErrorId : MissingEndParenthesisInMethodCall

    E:\approot>npp.exe /S

  3. Aaron says:

    Looks like for some reason the virtual Windows Server in Azure does not like accepting multiple encapsulation levels for “” strings. Had to “encapsulate” the actual powershell execution in a .ps1 script.

    powershell -executionpolicy unrestricted setup\download_npp.ps1
    npp.exe /S

Leave a Reply

Your email address will not be published. Required fields are marked *