Consuming installations from a local or hosted feed

For a variety of reasons, you may want to preserve your Boxstarter installation scripts inside of a Nuget package instead of a gist or loose file. Here are some common scenarios:
  • Your install is more than a single file script but contains other resources like configuration files or other application specific resources.
  • You want to host your package privately and maintain formal versioning.
  • You want all of your packages to be local with no dependencies on a connection to the world wide web.

This often involves one of three different ways of interacting with the Boxstarter powershell modules:
  • Host the modules on a network share and access via Boxstarter.bat. As long as a machine has access to this share, they can invoke a Boxstarter installation by simply invoking:
\\server\share\Boxstarter YourPackage
  • Host them on removable media like a thumb, SD or micro SD drive. You can invoke packages similar to the command above but using the media's drive letter.
E:\Boxstarter YourPackage
  • Host them locally and use the powershell cmdlets directly. This is also common if you use the cmdlets to invoke installations on remote machines/VMs.
$cred=Get-Credential SomeVM\mwrock
Install-BoxstarterPackage -ComputerName SomeVM -Package MyPackage -Credential $cred

This wiki will walk you through the steps to set this up.

Step 1

Get Boxstarter

If you have Chocolatey, the easiest way to do this is to simply call:
cinst Boxstarter.Chocolatey

This will download and install the Boxstarter modules to your PSModulePath. You could also download the Boxstarter zip file from Codeplex or http://Boxstarter.org. These contain a bootstrapper setup.bat that will install Chocolatey if not present.
setup.png

Then Boxstarter is fetched from Chocolatey.
installed.png

Step 2

Create a package

Boxstarter provides a set of cmdlets that make creating the the basic package skeleton simple.

After installing boxstarter, open a powershell console and run:
Import-Module Boxstarter.Chocolatey
New-BoxstarterPackage MyPackage

This will create a folder in your local boxstarter repo named MyPackage where you can store your install script and any other files your script might need. Often, it will not need any files other than a nuspec and ChocolateyInstall.ps1. Boxstarter just created those files for you with New-BoxstarterPackage. Your local boxstarter repo is where Boxstarter looks first for packages when asked to install a package. Packages here will always take precedence above any other public feed. You can always find the path to its location in the $Boxstarter global variable:
global.png

NOTE: If you receive an error complaining that Boxstarter could not be loaded because the execution of scripts is disabled, you need to execute a one time command as administrator:
Set-ExecutionPolicy Unrestricted -Force

Step 3

Write your install script

If you are already familiar with Chocolatey package scripts, you know how to do this already. The only difference with boxstarter scripts is that your script also has access to Boxstarter's API for configuring windows, running updates as well as logging and reboot control.

Lets open the ChocolateyInstall script that New-BoxstarterPackage created:
Notepad (Join-Path $Boxstarter.LocalRepo "MyPackage\tools\ChocolateyInstall.ps1")

There is already some boiler plate script there for error handling, but we will fill this in with something that will actually do something:
Update-ExecutionPolicy Unrestricted
Move-LibraryDirectory "Personal" "$env:UserProfile\skydrive\documents"
Set-ExplorerOptions -showHidenFilesFoldersDrives -showProtectedOSFiles -showFileExtensions
Set-TaskbarSmall
Enable-RemoteDesktop

cinst VisualStudio2013ExpressWeb
cinst fiddler4
cinst mssqlserver2012express
cinst git-credential-winstore
cinst console-devel
cinstm poshgit
cinstm windbg

cinst Microsoft-Hyper-V-All -source windowsFeatures
cinst IIS-WebServerRole -source windowsfeatures
cinst IIS-HttpCompressionDynamic -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

Install-WindowsUpdate -AcceptEula
This script does several things and leverages both Chocolatey and Boxstarter commands. Here is what this will do:
  • Set the powershell execution policy to be able to run all scripts
  • Move your personal folders to sync with skydrive
  • Make Windows Explorer tolerable
  • Enable Remote desktop to the box
  • Download and install a bunch of software
  • Enable windows features Hyper-V, IIS and the Telnet client
  • Create some shortcuts in the taskbar for common apps
  • Copy your console configuration file with your favorite settings
  • Install some Visual Studio extensions from the Visual Studio gallery
  • Install all critical windows updates

One final thing that needs to be done is to place the console configuration file in the package. This script installs the chocolatey console-devel package. A great console for Powershell and the command line. Personally, this is one app I am in all day and I have settings I want to replicate on any machine I use. There are lots of application that follow a similar model and you may want to include their configuration or settings files in your package. So we copy console.xml to our package's tools directory:
copy-item $env:appdata\console\console.xml (Join-Path $Boxstarter.LocalRepo "MyPackage\tools\console.xml") -Force

Step 4

Build the package to create your .nupkg file

Now that the script is complete we are ready to roll it all in to a single .nupkg file. If you want, you may also edit your .nuspec file that contains metadata regarding this package. If you simply plan to maintain this as a private package in your local repo, it is likely that this file needs no additional editing. See the Nuspec Reference at nuget.org for details about what this document describes.

Building the package is easy:
Invoke-BoxstarterBuild MyPackage
You now have a file called MyPackage.1.0.0.nupkg in your $Boxstarter.LocalRepo path.

Step 5

Publish your package to a feed (optional)

You may wish to publish your package to a public or private nuget feed allowing yourself and others to consume it from a well known location. You can use Chocolatey's cpush command to push the package to the public chocolatey feed. You may also use nuget's Push to publish to the MyGet.org community boxstarter feed or any other feed. To publish to the Boxstarter community feed, simply sign up for a free Myget account and run:
nuget push MyPackage.1.0.0.nupkg <Your MyGet API Key> -Source https://www.myget.org/F/boxstarter/api/v2/package
Of coarse you do not have to host your package on a nuget feed. You may simply keep it local.

How will Boxstarter find my package?
By default, Boxstarter searches for packages in the following order:
  1. Your local repo located at $Boxstarter.LocalRepo
  2. The Chocolatey.org public feed
  3. The Boxstarter Community feed at MyGet.org

You can configure Boxstarter to include additional feeds using the Set-BoxstarterConfig Cmdlet:
Set-BoxstarterConfig -NugetSources "$((Get-BoxstarterConfig).NugetSources);http://my/other/feed"
Now all packages hosted at http://my/other/feed will be searched last.

Step 6

Share your Repo

If you want to make it easy to share the boxstarter modules with others in your network so that they do not need to separately download Boxstarter, you can place them on a network share. Boxstarter exposes a convenience function for doing this:
Set-BoxstarterShare BoxShare

Now anyone with access to that share could invoke the install with:
\\yourcomputername\BoxShare\Boxstarter MyPackage

Or maybe you have a thumb drive kept on your key chain and you want to have this wherever you go. Simply copy your boxstarter install to the drive:
Copy-Item $Boxstarter.BaseDir G:\ -Recurse
This copies all modules and your local repo to the drive at G:\. Now you could install your package simply using:
G:\Boxstarter MyPackage

Bonus Step - Remote Installs

Installing your package to a remote machine

Maybe you dont want to share with others but would rather like to "push" installations to remote machines and VMs. Well that is now possible with Boxstarter! Boxstarter handles almost all of the remoting details so that installing a package remotely is practically no different from doing so locally.

Enable Powershell remoting on the target machine
In some cases you may not have to do this. If your machine is on a domain where group policy settings automatically enable Powershell Remoting or even just WMI, Boxstarter may be able to do this for you. If you are unsure, enabling it manually will not cause any harm and it is easy.

Open a Powershell window as administrator on the target machine and simply run:
Enable-PSRemoting -Force

Now on your machine where Boxstarter is installed:
$cred=Get-Credential=MyTargetMachine\myusername
Install-BoxstarterPackage -ComputerName MyTargetMachine -Package MyPackage -Credential $cred
Boxstarter will use the credential to connect to MyTargetMachine and will copy the Boxstarter modules and your LocalRepo packages to its local storage. It will then run the package on that machine. Boxstarter will configure your local machine to be able to connect to the remote machine and it may prompt you for permission to change settings. You can always provide the -Force parameter to silence the prompts.

Hello World

Lets now create a Hello World package to be installed on another machine. We will assume that you have enabled Powershell remoting on that machine as described above.

Now we will enter these commands to create our HelloWorld Package:
Import-Module Boxstarter.Chocolatey
New-BoxstarterPackage HelloWorld
Set-Content (Join-Path $Boxstarter.LocalRepo "HelloWorld\Tools\ChocolateyInstall.ps1") -Value "Write-Host 'Hello World!'" -Force
Invoke-BoxstarterBuild HelloWorld
This should look like this:
hwpkg.png
All we expect this package to do is print "Hello World!" to the console.

Now lets run the install on a remote machine:
hwfinish.png

Last edited Nov 10, 2013 at 9:51 AM by mwrock, version 13