What is Chocolatey?
Chocolatey is a PowerShell-driven package manager for Windows. In essence, it is a local agent and remote library (repository) that can be used to deploy and manage software installations (packages) on windows machines. It has dependence and conflict handling, as well as support for multiple (public and private) repositories of software installations. For our purposes, we’ll not worry too much about setting up a repository and creating packages, and instead use the public repository and packages.
Who and where is this for?
This is by no means a full-featured software management solution for a large organization. This solution would be best for labs, small organizations, or teams needing to manage base software sets on a minimal number machines. As the software packages are installed in real time into the machine, this is a solution for persistent VDI or Physical devices – not provisioned or non-persistent VDI.
Everything done here with Ivanti’s Environment Manager(EM) Policy could also be done with other products as well, as most of it is script driven. I like using Ivanti’s (Formerly AppSense) Environment Manager Policy platform, as it is a visual scripting language for automating activities within the user environment. It can be used for everything from basic drive and printer mapping, to complex conditional GPO application and, in this case, script execution.
What will we be doing
By the end of this exercise, we should end up with an EM policy and practice in place that will allow the dynamic installation of software packages from the Chocolatey public repo based on user AD group membership. A very simplified SCCM assignments system, if you will.
We’re going to assume a healthy EM policy environment, as well as understanding of EM and Active Directory (AD) administration. While mostly cut-and-paste, a healthy grasp of PowerShell and VBscript will also help here.
Packages and Groups
First, take a look around https://chocolatey.org/packages. This is the public repository of Chocolatey packages. You’ll find most mainstream software here and a healthy scoop of Free and Open Source Software (FOSS) to fill in the gaps.
For our purposes, we’ll be using AD groups with names matching those of the Choco packages we want to install, plus a defining header.
For the header we’ll use “ASCHOCO_” for AppSense Chocolatey. This way the groups are easy to keep track of, and it gives us an easy string item to filter on in PowerShell.
Looking at 7Zip as an example, we can see that it’s package name is “7zip”. However, there is also a package available called “7zip.install”. Without going into detail on the why here, you’ll usually want to use the .install version of a package where available. We’ll go ahead and create a group for this, using our headers’ standard: “ASCHOCO_7zip.install”
Before we get into the nuts and bolts of the Chocolatey fun, there are some limitations in EM that need to be worked around. Natively, EM has no way to pass information between the USER and SYSTEM execution environments. For example, if you elevate an action to run as SYSTEM, then try to reference the %USERNAME% variable, it will NOT return the user’s name, but rather SYSTEM.
This poses a problem here, as Chocolatey needs to be run as administrator, but also needs to access some user-specific information. We could of course use Ivanti’s Application Control solution to do some elevation work, but as they say: That’s another show.
To work around this USER/SYSTEM divide with EM alone, the policy leverages a staging directory (C:\appsense_stage). This staging directory is created at computer startup (and thus as SYSTEM), made user-writable (with icacls) and then used as a sandbox where the USER can write to and the SYSTEM can read from.
Later, policy will be using this directory to store a list of the apps that need to be installed for the user.
There is also a PowerShell action here to create a new log source for our later use.
We’ve attached the full skeleton to download below, but the meat of it really comes down to four steps: Create the staging environment, Install the Chocolatey platform, parse the current user’s group membership, and install the packages associated with those groups.
The Choco base install comes down via three lines of PowerShell. Essentially this installs the chocolatey base, quiets it down, and writes an event log. In the EM policy this Powershell script wrapped in some conditional logic and run at Pre-Desktop;
We’ve got a check to make sure that Choco is not already installed, then set a Logon message for the user and run the PowerShell to do the install. There is also an additional action here which installs the Chocolatey GUI package via the simple custom action.
Parse the user groups
In this phase of the policy, there is a vbscript which looks rather ugly, but actually accomplishes a very simple task: Read’s the current user’s AD groups, selects those that begin with ASCHOCO_ and then load the package names into a text file in C:\appsense_stage\applist.txt
Now that the user has a list of their Choco packages stored in a location that the SYSTEM can access, it’s time to run the third script in our series.
This is run at Desktop Created in order to negate any impact to logon time, but it could certainly be moved around to suit the use case.
There is a lot going on in this script, but its basically just parsing the text file created previously, then comparing that list of packages to the list of currently installed choco packages. If it finds assigned packages that are not installed it will install them, and if it finds installed packages that are not assigned it will uninstall them.
Keep in mind, the install/uninstall functionality here assumes management via Chocolatey – it is not checking the machine’s installed software manifest.
There isn’t much to see when it comes to testing this. Following a logon, all things assigned should be correctly installed and everything not – should not! Part of the package management script creates some event log notifications so we can validate with those:
On this test machine we can see two Uninstall events (ID 4002) and one Install event (4003). This is correct for this test, on which there were two choco packages installed that should not have been, and one assigned but missing;
This is a (reasonably) simple example of how the EM Policy platform can leverage FOSS tools like Chocolatey to really extend the functionality and capability of the product.
However, as you’ve probably noticed, we’re missing some additional functionality here. Specifically, there is no mechanism for upgradingpackages that are already installed. Further, we did not cover the creation of Private repositories, nor the building of custom packages.
Good news! In a future article, we’ll extend the functionality of this solution by creating our own private Chocolatey repository on prem, populating it with custom-built application packages and extending the scripted functionality to handle package upgrades.
Until next time!