Carrying on from my previous post on building an Automated Application Packaging Factory with Robotic Process Automation, I have been looking for ways to further streamline the process and wouldn’t you know it, Microsoft just released version 1.0 of the Windows Package Manager. I have been using WinGet on the Insider Build for a while to install some apps here and there but held off on going too crazy with it until it was made Generally Available.
If you are not familiar with WinGet, perhaps you are familiar with Chocolatey on Windows or RPM on Linux. They are Package Managers with extensive repositories of applications ready to install and manage with simple one liners. E.g.
Install applications with:
RPM: rpm -ivh <app>.rpm
Chocolatey: choco install <path/to/nuspec>
Windows Package Manager: WinGet Install <app>
Windows Package Manager has the advantage of having Microsoft behind it with all of their resources, there is an MSIX package available for easy deployment of the WinGet client and you can also now manage it with it with group policies. On launch there was more than 1,400 unique packages already available. Check out the repository of manifests for yourself or simply install the App Installer app and use the Winget search <appname> command from PowerShell. The search is one of the features of the product that I feel is a little lacking compared to Chocolatey and that is likely down to poor curation of the apps rather than the search itself, I bet. If you want to get a quick taste of how powerful this can be, when you have the App Installer app on your Windows 10 machine, open PowerShell and run Winget -upgrade –all to watch as it updates some of the apps that are a match on your machine.
It is early days for Windows Package Manager. Chocolatey has been around for 10 years and has a lot of time and effort put into it. I hope they ensure standardization and quality of the apps available in the long-term. One aspect I do like a lot is the variety of installer types they support, I hope they expand this even further. You could have an EXE and MSIX for a single app and specify which one you want to install via the WinGet command. I would love App-V, Cloudpaging and other formats in the future.
Just as I typed up this article, Microsoft released the YAML generator for Windows Package Manager (available in the Microsoft Store). It gives a GUI to help you generate the necessary text files. If like me you prefer to work from existing examples, you can just take an example from the manifests that are already publicly available on the repository. Key to the success of the likes of Windows Package Manager and Chocolatey is a consistent source for application updates as they are made available by the vendors. This is why it is worth highlighting community legends Aaron Parker and Dan Gough for their work on the Evergreen PowerShell Module and Nevergreen PowerShell Module which act as a mechanism for grabbing those Evergreen installer sources.
With the awesomeness of consistent sources to always pull the most up to date version of applications from and easy package managers like Chocolatey and Windows Package Manager, you have a great solution to easily deploy applications and keep them up to date with ease. When populating the URL for an installer, definitely consider these sources. If you find an app that does have a publicly available download URL that is not already available with WinGet and would like to share this with everyone in the community, you can submit the package to the Community Repository.
Of course, not all apps are provided with easy to access public downloads. Perhaps you have applications that are licensed just to your organization but you’d still like to have the option to install your custom package via WinGet. The good news is that you can host installers internally or on a private GitHub repository too and simply point to your own private source using the group policy template.
If you have been following my blog for a while you will know I have a background in Application Packaging. I tend to avoid locally installing applications into my RDSH and Virtual Desktops images. I even tend to avoid installing apps to my physical desktops, preferring to publish apps to the physical machines or deliver a dynamic app instead. My avoidance of locally installed apps has even greater emphasis now as I am conscious that my desktops could move to the cloud and the less storage consumed there the better. It will ultimately reduce cost and complexity of a cloud migration. Cloudpaging and AppVentix are great options for dynamic app delivery to help avoid locally installing apps with Cloudpaging being my go to option as it is able to handle all apps where as App-V and MSIX cannot.
That is why rather than rely on WinGet for delivering all of my apps, I will instead rely on it for a handful of agents and apps that I want to manage locally. For example, when I have vetted the latest version of ControlUp or Cloudpaging and want to upgrade my environment, I can then put the latest versions of the agents in my repository. The WinGet commands to install these handful of apps can run on startup of the machine so when I login all my agents are on the latest version with minimal effort. Basically my own internal Evergreen app feed for agents.
I can also leverage the WinGet Community Library Source plus my internal source to help streamline the automation of my packaging process for getting the majority of my apps in Cloudpaging for dynamic application delivery. I can use something like Jenkins or an RPA like Automai to run a check on a schedule to see if there is a new version of an app available in the WinGet sources and if so run the Process Scenario for that application to repackage it into Cloudpaging.
Whilst Windows Package Manager can greatly streamline the automation process for your re-packaging efforts, you will want to make note of various different directories, files, registry keys and registry values commonly used during the install of apps from Winget. You will want to add the likes of: C:\Program Files\WindowsApps, LocalAppData\Packages and AppData\Microsoft\Windows\PowerShell to your exclusion templates. There are also some Appx registry that can be excluded too. I guess consider this a convenience tax!
I have tried out Windows Package Manager as a way to streamline my Automated Application Package Factory even further. You can check out a quick demo above.
Essentially, if I use Winget as a feeder source for my packages, it significantly reduces the number of steps my robot has to carry out. It makes maintaining scripts even easier and you can simply use the same Global Scenario for any app you might want to leverage Windows Package Manager for and input the winget install command as a variable. No need to create a Scenario for each application! Just re-use the same WinGet Scenario for all apps.
By having a local source to install just a few apps on startup and also limiting the local packages installed in my images to just a few agents with Office, .NET and other larger shared components in the image you can get to that single gold image utopia with greater ease and without installing everything in the image. While I use App Masking on my published desktops for hiding certain printer objects and directories, I feel putting all apps into an image and then masking them is inefficient.
Oddly, enterprise applications are just as big a pain in the ass as they have always been but it seems like some vendors who were previously players in the app delivery modernization market have faded away, while others have pivoted to non-enterprise customer bases. IT teams also have fallen back into old habits of installing apps locally. Windows Package Manager is awesome and I could see it being a really great way to make MSIX even more mainstream once it has a higher rate of compatibility but I hope it doesn’t become a major crutch people use to keep using locally installed fat Win32 apps. It can be an excellent asset for continuous automation, keeping your apps evergreen perhaps using a combination of RPAs like Automai, Package Managers and Cloudpaging. Maybe throwing MSIX into the mix when it is more mature.