Chocolatey in the workplace

I talked previously about using Chocolatey for home use. It makes building a PC at home nice, simple and fast. It makes supporting non-technical friends and family nice and easy, ensuring you can build their computers how they want and keep them up-to-date with just a few simple commands (that can even be put in the scheduler, so neither you or they have to worry about them).

We’ve recently just completed a Windows 10 rollout at my college. I’m very pleased with it and, I think, the college’s staff and student customers also seem quite pleased. One of my team has worked incredibly hard on producing a perfect build of Windows 10 that revolves around a large image with most of the applications pre-installed. As we use SCCM and this is quite happy to deploy packages on a piecemeal basis itself, we had a lot of discussion about this and while we still think that SCCM is incredibly useful, it does have a few limits:

  • It’s based around old technology. SCCM is a development of Microsoft’s Systems Management Server and frankly, it shows. There are all kinds of weird and wonderful legacy dead ends to get lost in. This leads to…
  • It’s incredibly complex to use. If you’re someone like Boeing or Microsoft themselves then it’s about as complex as you need it to be, but for your average SME, a lot of the features are overkill.
  • It’s not terribly reliable. Let me explain: When you build a machine with SCCM you can assign several packages of configuration items (e.g. packages, settings) as part of the initial task sequence and these should all install fairly reliably. Packages that are installed after this initial task sequence seem to install in their own time. Debugging why these packages fail or take excessively long to install requires expert debugging of potentially dozens of logs spread between the client and the server.
  • SCCM requires a large and complex infrastructure deployment, potentially with many multiple servers needed for even a relatively simple SCCM deployment.

Chocolatey isn’t a magic fix for these issues but it does have a number of advantages:

  • Package installation is managed by the client (though you can push instructions to the client) and is much easier to predict and control.
  • It’s easier to upgrade packages with newer versions with Chocolatey vs. the process on SCCM to supersede old packages.
  • Chocolatey’s server infrastructure is relatively lightweight.
  • Chocolatey packages allow you to ensure that  a package is installed consistently whether manually or by automation – the install method is the same choco install $package -y command line statement either way and should produce the same result either way… which also makes it easy to examine and debug any issues.
  • Chocolatey allows you to install packages in a particular order. Of course you can do that with SCCM now, but if you’re looking at Intune and thinking of deploying Win 32 packages via powershell profiles then you might have noticed that powershell scripts don’t run in a particular order which means that any dependencies have to be resolved by you. Chocolatey also supports dependencies internally, by the way.

We’re currently using a hybrid deployment where we’ve built a “classic” image for our deployment but installed some of the packages into that baseline using chocolatey. This has improved our ability to generate new, consistent images much faster as well as being able to update packages in the future via chocolatey’s own update model, which will work well for devices that aren’t always on site.

With a combination of Chocolatey and a few other PowerShell tricks, it’s possible to run a couple of scripts to join a device to your domain and then install a baseline set of packages, as per my example scripts below.

Join domain and restart device

set-executionpolicy unrestricted
# Self-elevate the script if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] ‘Administrator’)) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
$CommandLine = “-File `”” + $MyInvocation.MyCommand.Path + “`” ” + $MyInvocation.UnboundArguments
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine

# Portable build script 1. Should be run on a Windows 10 Professional system that we wish to “build” as a domain device
# Does the following:
# 1. Ensure we’re elevated and if not elevate the session
# 2. Remove ‘bad’ apps that simply shouldn’t be on the workstation
# 3. Join the domain, placing the device in the Admin\Laptops OU in Workstations
# 3. Change product key to a Windows 10 Enterprise _KMS_ key. This ‘upgrades’ the system to Windows 10 enterprise but…
# …. the system MUST be on the network to find a KMS server on restart.
############ LAST UPDATE: 08/02/2018 Rob

# If you’re in this list you’re being uninstalled

Get-AppxPackage *officehub* | Remove-AppxPackage
Get-AppxPackage *skypeapp* | Remove-AppxPackage
Get-AppxPackage *getstarted* | Remove-AppxPackage
Get-AppxPackage *zunemusic* | Remove-AppxPackage
Get-AppxPackage *bingsports* | Remove-AppxPackage
Get-AppxPackage *xboxapp* | Remove-AppxPackage
get-appxpackage *oneconnect* | remove-appxpackage
get-appxpackage *phone* | remove-appxpackage
get-appxpackage *candy* | remove-appxpackage

# Prevent random “cloud content” nonsense from downloading
reg add hkey_local_machine\software\policies\microsoft\windows\cloudcontent /v DisableWindowsConsumerFeatures /t REG_DWORD /d 1
# Join the domain. Note credentials below for a non admin account with unlimited domain join rights.

$domain = “”
$username = “$domain\account”
$password = “Hunter2” | ConvertTo-SecureString -asPlainText -Force

$credential = New-Object System.Management.Automation.PSCredential($username,$password)
Add-Computer -DomainName “” -OUPath “OU=scripted,OU=build,OU=Workstations,OU=MySite,DC=your,DC=domain,DC=example,DC=com” -Credential $Credential
# change product key to your enterprise KMS workstation key and force a reboot.
Changepk.exe /ProductKey #####-#####-#####-#####-#####

shutdown /t 0 /r

Chocolatey Software Build

set-executionpolicy unrestricted
# Self-elevate the script if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] ‘Administrator’)) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
$CommandLine = “-File `”” + $MyInvocation.MyCommand.Path + “`” ” + $MyInvocation.UnboundArguments
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine

# Portable build script 2. Should be run on a Windows 10 Enterprise system that we wish to “build” as a college device
# Ensure that machine is Win 10 enterprise and domain joined first (run the domain join script first!)
# Does the following:
# 1. Ensure we’re running as admin and elevate if we’re not
# 2. install chocolatey
# 3. install apps using chocolatey repository
############ LAST UPDATE: 08/02/2018 Rob

# Now running elevated so launch the script:

# install chocolatey, chocolatey apps

Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString(‘’))
choco install -y office365-2016-deployment-tool /Shared
# choco install -y adobe-creative-cloud
choco install -y sql-server-management-studio
choco install -y 7zip.install
choco install -y vlc
choco install -y googlechrome

# Done, now reboot
shutdown /t 0 /r

You can obviously pick and choose from these examples as you wish.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.