The previous post in this series talked about why it is important to automate developer machine setup as well as getting Windows configured using DISM. This article will dive into automating the install of a common developer tool suite.
A Common Time-Suck: The Browse/Download Loop
Here is a common time-suck scenario. A developer gets a new machine from corporate IT. The machine had a common office suite of applications installed on it. It is lacking the tools every developer needs like Notepad++, Visual Studio, Visual Studio Code and so on. The developer navigates to each site and downloads the latest version of each application. As you can imagine this is a time suck because not only does a developer have to browse to each site, they also have to wait until the download finishes. Depending on the application and the internet connection speed this could take anywhere from a minute to 30 minutes per application. They can use the downtime waiting for applications to download by installing anything that completes. The key here is to know which application will most likely require a restart and which ones take the most time to finish.
Another Time-Suck: Placing the latest version in a shared folder
A common way I've seen organizations avoid the whole browse/download loop is to place all the common applications into a shared folder somewhere on the network. That helps a developer when they get a new machine, they can just go to a folder and install all the applications.
This leads to another problem. Someone has to keep those applications up to date. After a month, chances are most of those applications are already out of date.
Final Time-Suck: Manually Installing Applications
Both scenarios have a common problem: manually running the installer for each application. Some applications, like Visual Studio Code or Notepad++, install in less than a minute. Other applications, like Visual Studio 2017, can take up to an hour to install, depending on the options chosen. Developers would often wait to kick off that installer until the end of the day or until their lunch hour. Babysitting installations are tedious, a waste of time, and expensive.
Manually installing applications also open the problem of misconfiguration. My team does local database development, which means we had to install SQL Server. There are so many different ways to configure SQL Server. Or, Visual Studio 2017, there are a lot of individual components to choose from. It is too easy to have configuration drift between developers. Then you hear the inevitable phrase "it works on my machine."
Chocolatey to the Rescue! (Sort Of)
.NET Developers are used to making use of NuGet Packages in their applications. Fun fact about NuGet packages, they are nothing more than Zip files with additional metadata. The core concept is someone packages up a .dll (or set of .dlls) and specifies the other packages it depends on. Visual Studio downloads the NuGet package and installs it in a location for an application to use.
A team of people took that idea and applied to Windows Applications. The result of that effort is a product called Chocolatey. All you have to do is run a small setup script to get Chocolatey installed and then you are free to start using it. It has almost every developer tool possible under the sun.
- Visual Studio 2017
- Visual Studio Code
- Redgate SQL Toolbelt
Just to name a few. The syntax is very easy to use.
choco install sql-server-management-studio -y
That will go out and download SSMS from the web and install it automatically. No install wizards.
Please Note: You still have to purchase licenses for these applications. In a nutshell, Chocolatey simply wraps an application's MSI so the install can be scripted. Bottom line, if you install the Redgate toolbelt package, you better have a Redgate license.
Common Chocolatey Road-Blocks
Chocolatey has a lot of applications in its package repository (5300+ by my last count). But it doesn't have every application. One glaring example is SQL Server 2016 or 2017 Developer or Express.
Another issue is official support from software vendors. In a few cases, for example Octopus Deploy, I've seen the actual companies provide the Chocolatey packages. However, that seems to be the exception rather than the rule. Often times it is the community who manage the Chocolatey packages, not the software developers. Some applications are incredibly popular, like Notepad++, so the package is constantly updated. Other applications are less popular and only has one or two people responsible for maintaining them. In those cases, you will find the application is one or two versions of the most recent release.
It is important to note Chocolatey is a company. They offer the basic version of Chocolatey for free. For the vast majority of small development shops, the basic version will cover them. As your development shop grows and/or IT takes a more active role in software distribution, even for developers, you should give the paid versions of chocolatey a look. The paid versions have very nice features. I haven't had a chance to explore them because my particular use case is rather simple.
One final note, one which I find kind of funny, is the reaction of people when I tell them the name of the installer. One manager said to me "it is hard to take any package manager seriously when they call themselves Chocolatey." I told them using it is as easy as eating a chocolate bar but I don't think they were buying it.
Using Chocolatey In The Real World
To be honest, the roadblocks were really nothing more than speed bumps for how I wanted to use it. I wasn't trying to do anything fancy. All I wanted to do was write a script to install a bunch of applications without requiring developer intervention. Chocolatey accomplished that goal.
There were some quirks though. I had to add -y to the install command so the package would install "silently." Chocolatey does a good job of notifying you if you don't supply this parameter, so it wasn't a big deal. Closer to a quibble.
One final thing we did was setup a couple of scripts, depending on the role of the person doing the install. For example, Developers need Visual Studio, Node.js, Postman, etc. While a database developer only cares about GIT, Redgate and SSMS. We created "a core" script (which really is what the database developer used) and a regular developer.
The core script:
# CoreChocolateInstall.ps1 Write-Host "Installing Google Chrome" choco install googlechrome -y Write-Host "Installing Firefox" choco install firefox -y Write-Host "Installing 7-zip" choco install 7zip -y Write-Host "Installing Git" choco install git -y Write-Host "Installing Notepad++" choco install notepadplusplus -y Write-Host "Installing Paint.NET" choco install paint.net -y Write-Host "Installing SQL Management Studio" choco install sql-server-management-studio -y Write-Host "Installing Redgate SQL Toolbelt" choco install sqltoolbelt -y
The developer script, which is called after the core script:
# DeveloperChocolateInstall.ps1 Write-Host "Installing Redis" choco install redis-64 -y Write-Host "Installing NuGet Command Line" choco install nuget.commandline -y Write-Host "Installing .NET Targeting pack 4.5.2" choco install netfx-4.5.2-devpack -y Write-Host "Installing .NET Targeting Pack 4.6.2" choco install netfx-4.6.2-devpack -y Write-Host "Installing .NET Targeting Pack 4.7.1" choco install netfx-4.7.1-devpack -y Write-Host "Installing Postman" choco install postman -y Write-Host "Installing .NET Core" choco install dotnetcore-sdk -y Write-Host "Installing Node" choco install nodejs -y Write-Host "Installing DotPeek" choco install dotpeek -y Write-Host "Installing Visual Studio Code" choco install visualstudiocode -y Write-Host "Installing Visual Studio 2017 Professional" choco install visualstudio2017community -y Write-Host "Installing Visual Studio Desktop Workload" choco install visualstudio2017-workload-manageddesktop -y Write-Host "Installing Visual Studio .NET Core Tools" choco install visualstudio2017-workload-netcoretools -y Write-Host "Installing Visual Studio ASP.NET Workload" choco install visualstudio2017-workload-netweb -y Write-Host "Installing Visual Studio Node Workload" choco install visualstudio2017-workload-node -y Write-Host "Installing Resharper" choco install resharper -y
If we were to continue building out the script from the previous article we would end up with:
# BootstrapDeveloperMachine.ps1 Set-Location "<Location Where Scripts are located>" Write-Host "Kicking Off IIS Installer Script" PowerShell -file "Install_IIS.ps1" Write-Host "Kicking Off Core Application Script" PowerShell -file "CoreChocolateInstall.ps1" Write-Host "Kicking Off Developer Application Script" PowerShell -file "DeveloperChocolateInstall.ps1"
For our basic usage, Chocolatey worked great. We didn't get a chance to dive too deep into a lot of the more advanced features. We didn't really have to worry about performing additional steps during the installs. In some cases, you will have to do this. I encourage you to read through the package notes as well as comments by the package creators to see if that is the case. For example, Octopus Deploy's Tentacle package includes a link to perform additional steps on actually setting up the tentacle, including supplying the Thumbprint and install directory.
One thing I really liked about using this was I could kick off the script before a meeting and by the time I got back it was almost done. Sure, there were some minor cleanup tasks I had to perform, but all in all I've had nothing but a positive experience using Chocolatey.
I mentioned briefly the lack of SQL Server support with Chocolatey. In my next article in this series, I will walk through how to script that out.
I posted this article on Twitter and tagged Chocolatey. The folks over at Chocolatey liked it and offered me a tip from my previous post where I walked through how to use DISM using PowerShell. Well it turns out that Chocolatey supports DISM. Neat!
So instead of doing this:
# Install_IIS.ps1 Dism /Online /Enable-Feature /FeatureName:IIS-ASPNET /All Dism /Online /Enable-Feature /FeatureName:IIS-ASPNET45 /All Dism /Online /Enable-Feature /FeatureName:IIS-CertProvider /All Dism /Online /Enable-Feature /FeatureName:IIS-HttpRedirect /All Dism /Online /Enable-Feature /FeatureName:IIS-BasicAuthentication /All Dism /Online /Enable-Feature /FeatureName:IIS-WebSockets /All Dism /Online /Enable-Feature /FeatureName:IIS-ApplicationInit /All Dism /Online /Enable-Feature /FeatureName:IIS-CustomLogging /All Dism /Online /Enable-Feature /FeatureName:IIS-ManagementService /All Dism /Online /Enable-Feature /FeatureName:WCF-Services45 /All Dism /Online /Enable-Feature /FeatureName:WCF-HTTP-Activation45 /All Dism /Online /Enable-Feature /FeatureName:IIS-WindowsAuthentication /All
You can do this:
# Install_IIS.ps1 choco install IIS-ASPNET --source windowsfeatures choco install IIS-ASPNET45 --source windowsfeatures choco install IIS-CertProvider --source windowsfeatures choco install IIS-HttpRedirect --source windowsfeatures choco install IIS-BasicAuthentication --source windowsfeatures choco install IIS-WebSockets --source windowsfeatures choco install IIS-ApplicationInit --source windowsfeatures choco install IIS-CustomLogging --source windowsfeatures choco install IIS-ManagementService --source windowsfeatures choco install WCF-Services45 --source windowsfeatures choco install WCF-HTTP-Activation45 --source windowsfeatures choco install IIS-WindowsAuthentication --source windowsfeatures
I like this better because now I can combine all the Chocolatey install commands into one script.