Intune

Keeping your Intune base applications Evergreen

Hello there (Obi-Wan voice), keeping your Intune base applications up to date can be a challenge, today I want to show you how you keep your base applications up to date without 3rd party toolsets so when delivered to endpoints the latest versions are always installed to your end-users, thus ensuring that users are productive and that your endpoints are secure from any 3rd party vulnerabilities from the bat. We’ll use a combination of the Evergreen PowerShell module created by Aaron Parker and the PowerShell App Deployment Toolkit (PSADT).

It is important to note that there are products that can integrate into Intune that not only keep your base applications up to date, but also keep those same applications up to date on existing endpoints via patching, for example, a couple of these solutions are PatchMyPC and Scappman, both fantastic products. This article will only detail how you can keep base applications up to date for up to date software installations, it does not cover updating existing endpoint software versions.

Introducing the Evergreen PowerShell Module

The Evergreen PowerShell module keeps various vendor download URL’s up to date, for which we can utilise to download the very latest software binaries directly from vendor’s repositories, this means that there is no need to keep a private or community repository of installers, which can be a pain to manage at times. The module can be used for Azure Virtual Desktop, Configuration Manager, Intune, etc. In this case, we’ll utilise Intune via the Win32 app process to query Evergreen for various software URL’s, download the software and then trigger an installation based on that freshly downloaded software, hence keeping your base applications up to date at the time of deployment. Make sure you check out the various documentation on their website for more information.

Getting Started with Evergreen

Now that you know that Evergreen is, let’s install their PowerShell module, view some of the available software URLs, tailor these URL criteria and then finally download \ install the software in question.

Installing the Evergreen Module

On a device used to author and test software packages, open PowerShell (as administrator), type in the following to install and import the Evergreen module:

Install-Module -Name Evergreen
Import-Module -Name Evergreen
Installing the evergreen module for Intune

More info on installing the Evergreen module can be found here.

Viewing available Evergreen packages

Now that the Evergreen module has been installed and imported, run Find-EvergreenApp, this will return a list of supported applications for which we can use to download the installers:

Here’s a full list of supported apps at the time of writing:

NameApplication
1Password1Password
7zip7zip
7ZipZS7-Zip ZS
AdobeAcrobatAdobe Acrobat
AdobeAcrobatReaderDCAdobe Acrobat Reader DC
AdobeBracketsAdobe Brackets
AdoptiumTemurin11Adoptium Temurin 11
AdoptiumTemurin16Adoptium Temurin 16
AdoptiumTemurin17Adoptium Temurin 17
AdoptiumTemurin8Adoptium Temurin 8
AdoptOpenJDK11AdoptOpenJDK OpenJDK Official Binaries (JDK 11u)
AdoptOpenJDK16AdoptOpenJDK OpenJDK Official Binaries (JDK 16u)
AdoptOpenJDK8AdoptOpenJDK OpenJDK Official Binaries (JDK 8u)
AkeoRufusAkeo Rufus
AmazonCorrettoAmazon Corretto
AnacondaAnaconda
AnkiAnki
ArtifexGhostscriptArtifex Ghostscript
AtlassianSourcetreeAtlassian Sourcetree
AudacityAudacity
BeekeeperStudioBeekeeper Studio
BISFBase Image Script Framework
BitwardenDesktopBitwarden Desktop
BlenderLauncherBlender Launcher
BlueJBlueJ
CendioThinLincCendio ThinLinc
CitrixAppLayeringFeedCitrix Product Release Feeds
CitrixApplicationDeliveryManagementFeedCitrix Product Release Feeds
CitrixEndpointManagementFeedCitrix Product Release Feeds
CitrixGatewayFeedCitrix Product Release Feeds
CitrixHypervisorFeedCitrix Product Release Feeds
CitrixLicensingFeedCitrix Product Release Feeds
CitrixReceiverFeedCitrix Product Release Feeds
CitrixSdwanFeedCitrix Product Release Feeds
CitrixVirtualAppsDesktopsFeedCitrix Product Release Feeds
CitrixVMToolsCitrix VM Tools
CitrixWorkspaceAppCitrix Workspace app
CitrixWorkspaceAppFeedCitrix Product Release Feeds
ControlUpAgentControlUp Agent
ControlUpConsoleControlUp Console
Cyberduckiterate GmbH Cyberduck
dbeaverdbeaver
DebaucheeBarrierDebauchee Barrier
deviceTRUSTdeviceTRUST
DevToysDevToys
diagrams.netdiagrams.net
dnGrepdnGrep
FileZillaFileZilla
ForkDan Pristupov Fork
FoxitPDFEditorFoxit PDF Editor
FoxitReaderFoxit Reader
FreedomScientificFusionFreedom Scientific Fusion
FreedomScientificJAWSFreedom Scientific JAWS
FreedomScientificZoomTextFreedom Scientific ZoomText
FreeFemFreeFem
GeekSoftwarePDF24CreatorGeek Software PDF24 Creator
GephiGephi
GhislerTotalCommanderGhisler TotalCommander
GimpGIMP
GitForWindowsGit for Windows
GitHubAtomGitHub Atom
GitHubReleaseGitHub release
GoogleChromeGoogle Chrome
GreenshotGreenshot
gretlgretl
HandbrakeHandbrake
HashicorpBoundaryHashicorp Boundary
HashicorpConsulHashicorp Consul
HashicorpNomadHashicorp Nomad
HashicorpPackerHashicorp Packer
HashicorpTerraformHashicorp Terraform
HashicorpVaultHashicorp Vault
HashicorpWaypointHashicorp Waypoint
ImageGlassImageGlass
ImageMagickStudioImageMagickImageMagick Studio ImageMagick
JamTreeSizeFreeJAM Software TreeSize Free
JamTreeSizeProfessionalJAM Software TreeSize Professional
JASPJASP
JetBrainsIntelliJIDEAJetBrains IntelliJ IDEA
JetBrainsPyCharmJetBrains PyCharm
jqjq
jrsoftwareInnoSetupjrsoftware InnoSetup
KarakunOpenWebStartKarakun OpenWebStart
KeePassKeePass
KeePassXCTeamKeePassXCKeePassXC Team KeePassXC
LogMeInGoToMeetingLogMeIn GoToMeeting
LogMeInGoToOpenerLogMeIn GoToOpener
MasterPackagerMaster Packager
MattermostDesktopMattermost Desktop
McNeelRhinoMcNeel Rhino
MendeleyDesktopMendeley Desktop
MestrelabMnovaMestrelab Mnova
Microsoft.NETMicrosoft .NET Desktop Runtime
Microsoft365AppsMicrosoft 365 Apps
MicrosoftAzureDataStudioMicrosoft Azure Data Studio
MicrosoftAzureFunctionsCoreToolsAzure Functions Core Tools
MicrosoftAzureStorageExplorerMicrosoft Azure Storage Explorer
MicrosoftBicepMicrosoft Bicep
MicrosoftBotFrameworkEmulatorMicrosoft Bot Framework Emulator
MicrosoftEdgeMicrosoft Edge
MicrosoftEdgeDriverMicrosoft Edge
MicrosoftEdgeWebView2RuntimeMicrosoft Edge WebView2 Runtime
MicrosoftFSLogixAppsMicrosoft FSLogix Apps
MicrosoftOneDriveMicrosoft OneDrive
MicrosoftPowerShellMicrosoft PowerShell
MicrosoftPowerToysMicrosoft PowerToys
MicrosoftSsmsMicrosoft SQL Server Management Studio
MicrosoftTeamsMicrosoft Teams
MicrosoftVisualStudioMicrosoft Visual Studio
MicrosoftVisualStudioCodeMicrosoft Visual Studio Code
MicrosoftWindowsPackageManagerClientMicrosoft Windows Package Manager Client
MicrosoftWvdBootloaderMicrosoft Azure Virtual Desktop Agent Bootloader
MicrosoftWvdInfraAgentMicrosoft Azure Virtual Desktop Agent
MicrosoftWvdMultimediaRedirectionMicrosoft Azure Virtual Desktop Multimedia Redirection Extensions
MicrosoftWvdRemoteDesktopMicrosoft Remote Desktop
MicrosoftWvdRtcServiceMicrosoft Remote Desktop WebRTC Redirector Service
MinicondaMiniconda
MinitabMinitab
MiniZincIDEMiniZinc IDE
MirantisLensMirantisLens
MozillaFirefoxMozilla Firefox
MozillaThunderbirdMozilla Firefox
mRemoteNGmRemoteNG
MuseScoreMuseScore
Naps2Ben Olden-Cooligan NAPS2
NETworkManagerNETworkManager
NevcairielLAVFiltersNevcairiel LAV Filters
Nomacsnomacs Image Lounge
NotableNotable
NotepadPlusPlusNotepad++
OBSStudioOBS Studio
OctopusDeployServerOctopus Deploy Server
OctopusTentacleOctopus Tentacle
OpenJDKOpenJDK
OpenShellMenuOpen-Shell-Menu
OpenWebStartOpenWebStart
OperaBrowserOpera Browser
OperaGXBrowserOpera GX Browser
OracleJava8Oracle Java 8
OracleVirtualBoxOracle VirtualBox
PaintDotNetdotPDN LLC Paint.NET
PaintDotNetOfflineInstallerdotPDN LLC Paint.NET
PandocPandoc
PDFForgePDFCreatorpdfforge PDFCreator
PeaZipPeaZipPeaZip PeaZip
PostmanPostman
PraatPraat
ProjectLibreProjectLibre
ProtegeProtege
PSAppDeployToolkitPSAppDeployToolkit
PSFPythonPSF Python
PuTTYPuTTY
RCoreTeamRforWindowsR Core Team R for Windows
RDAnalyzerRemote Desktop Analyzer
RingCentralRingCentral
RStudioRStudio
SafeExamBrowserSafe Exam Browser
SAGAGISSAGA-GIS
ScooterBeyondCompareScooter Beyond Compare
ScratchScratch
ShareXShareX
SignalDesktopSignal for Windows
SlackSlack
SmartBearSoapUISmartBear SoapUI
StefansToolsgregpWinStefans Tools gregpWin
SumatraPDFReaderSumatra PDF Reader
TableauDesktopTableau Desktop
TableauPrepTableau Prep
TableauReaderTableau Reader
TeamViewerTeamViewer
TechSmithCamtasiaTechSmith Camtasia
TechSmithSnagItTechSmith SnagIt
TelegramDesktopTelegram Desktop
TelerikFiddlerClassicTelerik Fiddler Classic
TelerikFiddlerEverywhereTelerik Fiddler Everywhere
TerminalsTerminals
TeXstudioTeXstudio
TogglDesktopToggl Desktop
TorProjectTorBrowserTor Project Tor Browser
USBPcapUSBPcap
VastLimitsUberAgentvast limits uberAgent
VeraCryptVeraCrypt
VercelHyperVercel Hyper
VideoLanVlcPlayerVideoLan VLC Player
VisualCppRedistAIOVisualCppRedistAIO
VMwareHorizonClientVMware Horizon Client
VMwareToolsVMware Tools
voidtoolsEverythingvoidtools Everything
Win32OpenSSHWin32-OpenSSH
WinMergeWinMerge
WinSCPWinSCP
WiresharkWireshark
WixToolsetWiX Toolset
ZoomZoom
ZoteroZotero

Note: You can use Find-EvergreenApp | Select-Object Name, application | Export-CSV -path C:\Evergreenapps.csv command to reproduce the above list.

Downloading the Software

Now that we know which applications are supported, let’s query these applications further to see what download options we have using the Get-EvergreenApp command, I’ll use Adobe Reader DC as an example, so based on the above list, you’ll need to gather the name of the application, which in this case is AdobeAcrobatReaderDC, add this into your Get-EvergreenApp command and you’ll see all of the options such as language, architecture, etc. Here’s the command to query Adobe Reader DC Get-EvergreenApp -Name AdobeAcrobatReaderDC, which returns various results, like so:

Some of the options change based on the software being queried, here’s Mozilla FireFox as an example:

As you can see we have new options for the software channel, file types (MSI, EXE, etc). Let’s stick to our AdobeReaderDC example, based on the results, I can see that a download URL that is relevant to the English (UK) language and architecture of x64, which is what I’m after, so let’s now be more specific with our query of Get-EvergreenApp -Name AdobeAcrobatReaderDC | Where-Object { $_.Architecture -eq “x64” -and $_.Language -eq “English (UK)”}:

The goal is to get to one URL to be listed, which we’ll use to download and install, thus keeping us Evergreen.

Downloading and Installing the software

Now that we have our URL returning what we want to install, let’s put it all together into a fairly simple script, this script will be used later in our PSADT package and then uploaded into Intune for wide distribution, the below script installs the Evergreen module, downloads the Adobe Reader DC UK English x64 edition, triggers the installation process and then finally deletes the installer:

## Installs latest version of Adobe Reader DC via Evergreen PowerShell module
# Trust PowerShell Gallery
If (Get-PSRepository | Where-Object { $_.Name -eq "PSGallery" -and $_.InstallationPolicy -ne "Trusted" }) {
    Install-PackageProvider -Name "NuGet" -MinimumVersion 2.8.5.208 -Force
    Set-PSRepository -Name "PSGallery" -InstallationPolicy "Trusted"
}
#Install or update Evergreen module
$Installed = Get-Module -Name "Evergreen" -ListAvailable | `
    Sort-Object -Property @{ Expression = { [System.Version]$_.Version }; Descending = $true } | `
    Select-Object -First 1
$Published = Find-Module -Name "Evergreen"
If ($Null -eq $Installed) {
    Install-Module -Name "Evergreen"
}
ElseIf ([System.Version]$Published.Version -gt [System.Version]$Installed.Version) {
    Update-Module -Name "Evergreen"
}
# Download Latest version of Adobe Reader DC via Evergreen
$AdobeReaderDC = Get-EvergreenApp -Name AdobeAcrobatReaderDC | Where-Object { $_.Architecture -eq "x64" -and $_.Language -eq "English (UK)"}
$AdobeReaderDCInstaller = $AdobeReaderDC | Save-EvergreenApp -Path "C:\Temp\AdobeReaderDC"
# Install Adobe Reader DC
Start-Process -FilePath "$AdobeReaderDCInstaller" -args "/sAll /msi /norestart /quiet ALLUSERS=1 EULA_ACCEPT=YES" -Wait -Verbose
# Cleanup temp directory
$AdobeReaderDCInstaller | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue

Make sure you test this on a device and verify your results. That’s it, that’s the beauty of the Evergreen module, simple, effective and if you open up the Adobe Reader DC application, you’ll see that you’re all up to date, as the software is coming directly from the vendor:

Let’s move into wrapping this up into a PSADT package.

PowerShell App Deployment Toolkit

I won’t go into how to source and package up PSADT step by step as such, but I do have some examples on my Github page, which includes the Adobe Reader DC Evergreen package, anything with Evergreen in the title is using the Evergreen download URLs as discussed previously. I’ll go over briefly what’s in my Adobe Reader DC Evergreen PSADT package on Github, so you can easily replicate this for your own packages, first download the items from my Github page, unzip, find the directory of AdobeReaderDC_Evergreen_PSADT and copy it to a safe location, the directory should look like so:

The installation script that I referenced earlier is located in the Files folder, then in the Deploy-Application-ps1 file is where the magic happens, open this up and I’ll briefly describe the important lines of code which differ from the default script contents.

Lines 64-72 detail metadata information about the actual software package:

Line 120, shows a message to the end-user asking them to close AdobeReaderDC if they already have it open with a count down of 10 minutes: Show-InstallationWelcome -CloseApps ‘Acrobat’ -CheckDiskSpace -PersistPrompt -CloseAppsCountdown 600:

Lines 139-141 this is the actual installation command, as you can see if it referencing a PowerShell script within the Files folder, which is the exact same installation script you saw earlier:

## <Perform Installation tasks here>

[string]$MyArguments = “-ExecutionPolicy Bypass -NoLogo -File `”$dirFiles\InstallAdobeReaderDC.ps1`” “

Execute-Process -Path “$PSHOME\powershell.exe” -Arguments $MyArguments

Line 149: Deletes the C:\temp directory to ensure all is clean from the installer:  Remove-Folder -Path “$env:SYSTEMDRIVE\temp” -ErrorAction SilentlyContinue

Line 150: Deletes the default Adobe Reader DC shortcut from the public desktop: Remove-File -Path “$envCommonDesktop\Adobe Acrobat DC.lnk” -ErrorAction SilentlyContinue

Line 163: Uninstallation prompt to close AdobeReader if running: Show-InstallationWelcome -CloseApps ‘Acrobat’ -CloseAppsCountdown 600

Line 191: Performs the uninstallation of AdobeReaderDC: Remove-MSIApplications -Name ‘Adobe Acrobat DC’

Also, within the AppDeployToolkit\AppDeployToolkit.xml, I’ve made three changes to the defaults, which I’ll go over.

Lines 23 and 59: I’ve updated the log path so it goes to the IntuneManagementExtention\Log path, this is particularly handy when capturing diagnostics from an Intune console action, this ensures that PSDAT installation logs are also captured:

<Toolkit_LogPath>$envProgramData\Microsoft\IntuneManagementExtension\Logs</Toolkit_LogPath>

<MSI_LogPath>$envProgramData\Microsoft\IntuneManagementExtension\Logs</MSI_LogPath>

Line 92: I’ve turned off balloon notifications as Intune produces it’s own:  <ShowBalloonNotifications>False</ShowBalloonNotifications>

That’s it, that’s all the PSADT configuration, to test the installation via the PSADT framework, run the following commands on your test device:

Install: Deploy-Application.exe -DeploymentType install

Uninstall: Deploy-Application.exe -DeploymentType Uninstall

Ensure all is well before proceeding with the example I’ve shown or with your own package, finally, wrap the entire contents of the directory including the serviceui.exe file into an .Intunewin file (I won’t demonstrate how to do this as I’m sure you’re familiar with the win32 wrapping process).

Creating the Intune application

Now that you have your PSADT package, based on downloading installers via Evergreen and triggering an install to make sure you always have the latest version of the software, we need to upload the .intunewin packaged in the previous section into Intune and create our application, let’s get started.

Log into MEMAC Admin centre, go to Windows > Apps, Add:

A new wizard will appear, select Win32 and then select the .Intunewin packaged previously, a new window will then appear asking for metadata, file it out to suit your needs, here’s mine:

Now onto the installation commands, they’re slightly different from our lab environment due to the utilisation of ServiceUI.exe, the reason we use serviceui.exe is to ensure prompts are produced to end-users even though the installation process is triggered using the system account, serviceui.exe is part of the Microsoft Deployment Toolkit, it is widely used as a junction between the processes running as NT Authority\System and end user sessions either to display a message or accept input from an end user whereas they wouldn’t normally be visible whilst keeping the original process in the system context, this comes in handy when end-users do not have local administrator rights but input is required when installing applications for example or this in case, display a message about running processes and then install an application in system context. The installation and uninstallation commands are as follows:

Install: .\ServiceUI.exe -Process:explorer.exe Deploy-Application.exe -DeploymentType install

Uninstall: .\ServiceUI.exe -Process:explorer.exe Deploy-Application.exe -DeploymentType uninstall

Note: I also included the commands into the cmds.txt within my GitHub repo examples too.

Requirements:

Detection methods, I tend to use a script to detect the presence of the application when using Evergreen, I don’t do any version control either for obvious reasons, this detection method will scan both the 64-bit and 32-bit registry app installation locations for a display name LIKE Adobe Reader DC, here’s the script, make sure this returns correct results on your test device before proceeding (e.g. If Adobe Reader DC is installed then the script should display “Installed”, if NOT installed, the script should display nothing):

$DisplayName = "Adobe Acrobat DC*"
$check = $false
Get-ChildItem -Path HKLM:\software\microsoft\windows\currentversion\uninstall -Recurse -ErrorAction SilentlyContinue | % {if ((Get-ItemProperty -Path $_.pspath).DisplayName -like $DisplayName) {$check = $true}}
Get-ChildItem -Path HKLM:\software\wow6432node\microsoft\windows\currentversion\uninstall -Recurse -ErrorAction SilentlyContinue | % {if ((Get-ItemProperty -Path $_.pspath).DisplayName -like $DisplayName) {$check = $true}}
if ($check) {Write-Host "Installed"}
else {}

Note: I also included the script within my GitHub repo examples too. In this example, the script was called AdobeReaderDC_DetectionScript.ps1

That’s it, attempt to run the installation against a test device via Intune first to ensure all is well.

Note: Be aware that that the download of data via this method is direct to various vendor websites, as a consequence delivery optimisation (DO) will not save you bandwidth in this scenario.

Examples and Conclusion

Don’t forget that working examples are available on my GitHub page, you can simply package any directory with Evergreen in the title to a .Intunewin file and upload it into Intune ASIS, I’ve also included the detection method scripts and installation \ uninstallation commands in each directory.

This is quite a blog post, but I hope you can see how easy it is to keep your base applications up to date using a combination of Evergreen and PSADT, if you have any questions or have something to share, please leave me a comment, or reach out to me on Twitter.

One thought on “Keeping your Intune base applications Evergreen

  • I like your solution and it provides a good method of always installing the latest version of an application directly from the source, but what if someone had the application installed as required and a new version would be released a month later. Looking at the detection method this new version would not be installed, because the current version is detected. This way is seems new updates will never be installed once the application is present.

    I think you could solve this by adding a detection that looks for a specific installed version of the application, but since you never know when that version exactly is when the user receives the application I wonder how we can work around this without too much manual intervention (which would take away the main purpose of this app which is set it and forget it)

    Any ideas on this?

Comments are closed.