When it comes to IaaS cloud computing, one of the main requirements is the ability to automate all processes. After all, while the cloud environment can just be another platform to host IaaS machines, you wouldn’t like to keep building machines manually. Plus, we all want to follow NIST’s definition of cloud computing and it’s not a cloud until self-served (which would be a tad difficult if not automated).

To address this requirement, there are many scripting technologies and configuration management tools that have become available in recent years.

However, without configuration management tools, deploying a fully-automated Windows build can still be a challenge.  This is because Windows requires a reboot after joining the machine to the domain. While a lot of configuration can be done as part of a script running at first boot, there are certain things you may need to do after joining the machine to a domain or after a reboot.

For example:

  • Adding domain groups to local groups for various types of access
  • Installing software that requires domain membership
  • Installing something that requires a reboot in order to do further configuration

Actually, you may even have size limits on your scripts.  Amazon Web Services is one example where “UserData” has a limit of 16KB for the script that can fit and there is only so much that you can do with that.

In such situations, having a simple solution that can run scripts serially after every reboot is very useful. The purpose of this post is to mention one such solution that I’ve found quite useful and may help. It’s PowerShell based but it’s the concept that is important and is transferable to other technologies too.

So, how about scheduling a script that runs on next startup. Here’s a sample script that you could make part of your script to achieve it:

$schAction = New-ScheduledTaskAction -Execute "Powershell.exe" -Argument '-NoProfile -WindowStyle Hidden -File "C:\Scripts\<some config>.ps1"'

$schTrigger = New-ScheduledTaskTrigger -AtStartup

$schPrincipal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest

Register-ScheduledTask -Action $schAction -Trigger $schTrigger -TaskName "Configuration" -Description "Scheduled Task to run configuration Script At Startup" -Principal $schPrincipal

This will add a scheduled job to run the PowerShell script to the scheduler which runs at next startup. As this is running under a privileged account, it doesn’t require a login to continue. Of course, it can also be a function but just wanted to show it in the most simplistic fashion.

As we want everything to be tidy, the script that you are scheduling should contain something that removes it from the scheduler as it will have run already. Here’s another sample that can become part of that script:

Unregister-ScheduledTask -TaskName "Configuration" -Confirm:$false

Note: It’s important to match -TaskName with the one you scheduled earlier. Doing this, removes the script from the scheduler, thereby preventing it from running at next boot. I typically put this at the beginning of the script to avoid a situation where an error later in the script causes this not to run.

Rinse and repeat for as many scripts as you want.

Hope this helps!