Easily Script Machine Reinstalls with Boxstarter / by Matt Wrock

boxLogoAlmost a year ago now I started this small project, Boxstarter.  The project has sustained many interruptions as I have had busy spurts at work and involvements with other projects. It has gone through some serious refactorings moving from a scrappy script to a larger codebase organized into a few PowerShell modules and a suite of unit tests. A lot of its original code I moved over to Chocolatey and I plan to continue to contribute to Chocolatey where it makes sense. Chocolatey Rocks! So overall, I have probably rewritten this thing twice and now I feel it is far from finished but represents a nice base that makes “Box Starting” a much simpler and repeatable process.

Repaving Sucks

I think that pretty much says it. The idea of creating Boxstarter came to me when I had a SSD die and had to do a dreaded repaving of my machine shortly followed by installing several Windows 8 revisions from Consumer Preview to RTM. At the time, I was in the middle of a project where I was using powershell to automate a 50 page deployment document. So I knew if I can automate installing AppFabric, network shares, multiple web apps and other infrastructure settings, surely I can script the build of my own PC.

Then I found Chocolatey

So as I was looking in to how I could setup a fully functioning dev environment on one box to be just as  I left it on another, I inevitably discovered Chocolatey. Chocolatey is built on top of Nuget but instead of maintaining library packages for you dev project, it manages machine wide software package installations. This is good for several reasons:

  • Its plain simple to install apps that can be tedious to install on your own. Instead of hunting around the internet for the download page, forgetting to uncheck the animae tool bar download and waiting three minutes to click the next button, just type CINST <your app> and be done with it. Next time its time for a mega Visual Studio install session, save yourself and use CINST VisualStudioExpress2012Web.
  • Now lets say you have a bunch of apps you installed with Chocolatey and want to just update everything. Simply type CUP ALL.
  • The very best thing of all: create a “meta-package” or package.config and now you can install all of your apps in one go. Chocolatey just iterates the list and installs everything one by one along with all of their dependencies.

If you have not heard of or have not used Chocolatey, do yourself a favor and install it now.

What is Boxstarter? Chocolatey Tailored Specifically for Fresh Machine Installs

Chocolatey is awesome, but having done a TON of experimentation with automating new machine setups of all sorts of flavors, OSs and complexity, I have learned that setting up an environment can be much more than simply running a chain of installers.

Let me quickly list the benefits of Boxstarter and then I’ll dive into a few highlights:

  • Ensures the entire install session runs as administrator. This avoids occasional prompts to elevate your shell and limits it to just one at the beginning assuming you are not already running as admin.
  • Shuts down the Windows Update Service and Configuration Manager if installed during the install session. These can often interfere with installations causing installs to fail because either an update is blocking the install you are trying to run or they install patches that require a reboot before other software can be installed.
  • Can discover if there is a pending reboot and will reboot the machine and restart the install if asked to reboot. If written correctly, the install will pretty much start from where it left off. Further, Boxstarter can automatically log you in so you don’t have to stick around.
  • Boxstarter handles the initial installation of Chocolatey and if you are on a fresh win7 or server 2008R2, it will install .net 4.0 first which is a Chocolatey prerequisite.
  • Provides a bunch of helper functions for tweaking various windows settings.
  • Automates installation of critical windows updates.
  • Makes it easy to setup a local Boxstarter repo on your network so any connected machine can kickoff a install with one command.
  • Provides helper functions making it easy to create your own Boxstarter package.

The Boxstarter Killer Feature: Handling Reboots

I used to spend hours tweaking my install scripts, playing with ordering and various tricks to avoid having to reboot. There finally came a point when I realized this was pointless. Win8/Server2012 are a lot more reboot resistant but are still prone to them. Things get worse here when you are installing patches and more complicated apps like Visual Studio an/or SQL Server. I have realized that Reboots happen and can be unpredictable so the only thing to do is be able to deal with them.

The challenges are making sure the install scripts picks up right after restart, ensuring that the script does not spark a UAC prompt and block the setup, have it securely store your credentials so that it automatically logs back on after reboot but turns off auto logins after the script completes.

Boxstarter does all of these things. As a Boxstarter package author, you simply need to compose your packages to be repeatable. This means you should be able to run it again and again without error or data loss and ideally it should skip any setup processes that have already been run.

What is a Boxstarter Package?

Its just a Chocolatey package, but its intent is usually to either install a fresh environment or to lay down a complicated install chain that is highly prone to needing one or even several reboots. You can store them locally, on Chocolatey or on Myget or anywhere else you configure Boxstarter to look.

Show me the Code

First. Install Boxstarter.  The easiest way to do this is to install Boxstarter.Chocolatey from Chocolatey or download the zip from the CodePlex site and run the setup.bat. This installs all dependent modules and puts them in your user module path.

Next create a package, build it and deploy your repository to b consumed from anywhere in your network or even a thumb drive. Like this:

#After extracting Boxstarter.1.0.0.zip on MYCOMPUTER
Import-Module $env:appdata\boxstarter\Boxstarter.Chocolatey\Boxstarter.Chocolatey.psd1
#Create minimal nuspec and chocolateyInstall
New-BoxstarterPackage MyPackage
#Edit Install script to customize your environment
Notepad Join-Path $Boxstarter.LocalRepo "tools\ChocolateyInstall.ps1"
#Pack nupkg
Invoke-BoxstarterBuild MyPackage

#share Repo
#Or Copy to thumb drive G
Copy-Item $Boxstarter.BaseDir G:\ -Recurse

#Logon to your bare Windows install
\\MYCOMPUTER\Boxstarter\Boxstarter Mypackage

#Enter password when prompted and come back later to find all your apps installed


Now lets look at what an install package might look like

Install-WindowsUpdate -AcceptEula
Update-ExecutionPolicy Unrestricted
Move-LibraryDirectory "Personal" "$env:UserProfile\skydrive\documents"
Set-ExplorerOptions -showHidenFilesFoldersDrives -showProtectedOSFiles -showFileExtensions

cinstm VisualStudioExpress2012Web
cinstm fiddler
cinstm mssqlserver2012express
cinstm git-credential-winstore
cinstm console-devel
cinstm skydrive
cinstm poshgit
cinstm windbg

cinst Microsoft-Hyper-V-All -source windowsFeatures
cinst IIS-WebServerRole -source windowsfeatures
cinst IIS-HttpCompressionDynamic -source windowsfeatures
cinst IIS-ManagementScriptingTools -source windowsfeatures
cinst IIS-WindowsAuthentication -source windowsfeatures
cinst TelnetClient -source windowsFeatures

Install-ChocolateyPinnedTaskBarItem "$env:windir\system32\mstsc.exe"
Install-ChocolateyPinnedTaskBarItem "$env:programfiles\console\console.exe"

copy-item (Join-Path (Get-PackageRoot($MyInvocation)) 'console.xml') -Force $env:appdata\console\console.xml

Install-ChocolateyVsixPackage xunit http://visualstudiogallery.msdn.microsoft.com/463c5987-f82b-46c8-a97e-b1cde42b9099/file/66837/1/xunit.runner.visualstudio.vsix
Install-ChocolateyVsixPackage autowrocktestable http://visualstudiogallery.msdn.microsoft.com/ea3a37c9-1c76-4628-803e-b10a109e7943/file/73131/1/AutoWrockTestable.vsix


Whats going on here?

Boxstarter installs critical updates, sets your powershell execution policy to unrestricted, makes windows explorer usable, installs some great apps, installs some of your favorite windows features, moves your Documents library to skydrive (I love this for the truly portable desktop), installs your favorite VS extensions and sets up things like pinned items and task bar size preference.

A lot of this functionality comes to you compliments of Chocolatey and others are specific to Boxstarter.

What’s Next?

As I see it, this is just the absolute base functionality so far. There is so much more to be added to make an installation process truly seamless. Here are some features I plan to begin soon:

  • Create a Boxstarter package automatically based on software already installed and windows features turned on to mimic these on another machine.
  • While Boxstarter can be installed and run either on bare metal or a VM, I want to make Boxstarter the powershell/hyper-v equivalent of Vagrant. Making the deployment of scripted VMs simple.
  • Add a one-click installer making a an easy one liner install command possible remotely.

There is a lot of Boxstarter functionality I have not covered here. I plan to blog fairly regularly providing brief posts describing various ways Boxstarter can augment your automation. If you want to learn more now. Checkout the Boxstarter Codeplex site which has complete documentation of all features and commands.