Intune allows to automatically have software installed on target devices. I found a nice write-up on using this in conjunction with Chocolatey, but realized it could be made much easier. First we’ll prepare the files locally which needs to be done only once, instead of for each application.
There are three things i am trying to accomplish. First one is to deploy a Chocolatey application from intunet, the second is to auto update the appications and the third is to use an Intune application detection script that uses Chocolatey.
Install chocolatey
You will need the following Microsoft tool:
GitHub – microsoft/Microsoft-Win32-Content-Prep-Tool: A tool to wrap Win32 App and then it can be uploaded to Intune
Frist we need to create a powershell script that will install Chocolatey. Save the code below to an install.ps1 file.
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
Now let’s create a .intunewin
file for our Chocolatey install. In the directory run the following in Powershell:
.\IntuneWinAppUtil.exe -c .\ -s install.ps1 -o .\
This creates an .intunewin
file which we can re-use in Intune for each application we wish to install using Chocolatey.
Create a new Windows app (Win32) in intune and select the .intunewin we just created and use the following commands. Now i didn’t make an uninstall.ps1 for Choco because i didn’t see the need to uninstall Choco but you can make one if you want and add it to the .intunewin
Install command
powershell.exe -executionpolicy bypass .\install.ps1
Uninstall command
powershell.exe -executionpolicy bypass .\uninstall.ps1
Install behavior
System
Device restart behavior
App install may force a device restart
Return codes
0 Success
1707 Success
3010 Soft reboot
1641 Hard reboot
1618 Retry
For the detection rule of Chocolatey .
Path
C:\ProgramData\
File or folder
chocolatey
Detection Method
File or folder exist
64bit
Yes
Add a choco application
Save the script below as install.ps1
in an empty directory, and download IntuneWinAppUtil.exe
into that directory as well.
param(
[string]$package = "",
[switch]$uninstall = $false
)
if ($uninstall) {
choco uninstall $package -y
} else {
choco upgrade $package -y
}
upgrade
will install the package if it isn’t yet installed. Two fish
You can use this script directly by running ./install.ps1 <package name> [-uninstall]
. We’ll use Intune to automate installation of packages.

Now let’s create a generic .intunewin
file for all our Chocolatey apps. In the directory run the following in Powershell:
.\IntuneWinAppUtil.exe -c .\ -s install.ps1 -o .\
This creates an .intunewin
file which we can re-use in Intune for each application we wish to install using Chocolatey.
Create an intune app
When creating an Intune app, set it as a Windows app (Win32)
and during the wizard set the install command to
powershell.exe -executionpolicy bypass .\install.ps1 <package name>
And the uninstall command to
powershell.exe -executionpolicy bypass .\install.ps1 <package name> -uninstall
Detection
We can also use Chocolatey to detect our package. For this we check using choco
if the app exists locally. For that, create the following script:
choco feature enable --name="'useEnhancedExitCodes'" -y
$PackageName = "PACKAGENAME"
choco list -e $PackageName --local-only
exit $LastExitCode
Be sure to replace PACKAGENAME with the name of the package, as used by Chocolatey.
Set the detection rules format to Use a custom detection script, and upload the just created script. Make sure Enforce script signature check and run script silently is set to No.
The above script does some fancy things:
- It enables the
useEnhancedExitCodes
feature, which ensures the exit code is 2 when the package doesn’t exist. Else it will return 0 because it had no issues checking that the package didn’t exist. This setting just needs to be set once, but we place it here to always be sure it is enabled. --local-only
ensures it uses the local index of apps, else it will always return true because the package exists in the Chocolatey repository.- Explicitly exit using the chocolatey given exit code, as powershell may not properly pass this to InTune.
AutoUpdate
So the easiest way to update all your choco apps would be to deploy a scheduled task from a powershell script with intune that will run a choco upgrade all command in powershell. I’ve came up with the following solution that works for our situatiion.
What i did is to add a New-ScheduledTaskAction with an Execute ‘Powershell.exe’ -Argument ‘-NoProfile -WindowStyle Hidden so that there is no visual output when running. The command is a simple – “choco upgrade all. Its nice to ouput a log from this action so that the servicedesk can check a logging if there where any problems with a new application. So i gave a Out-File -FilePath C:\Windows\Logs\choco-update-log.txt”‘ .
I’ve set the trigger of running this script at login ($trigger = New-ScheduledTaskTrigger -AtLogOn) because we are mainly targtting laptops so a night timed schedule isnt possible and i dont want users to get a update during daytime. But you can change this variable to whatever suits your situation.
I let the task run under the Local Service Account System $STPrin = New-ScheduledTaskPrincipal -UserId “SYSTEM” -LogonType ServiceAccount
Finaly i’ve added al the variables in one line to register the task. You can change the -Taskname and – Description. to whatever suits you. Also this tasks only runs when logging in and the machine is connected to a powersupply.
$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '-NoProfile -WindowStyle Hidden -command "choco upgrade all | Out-File -FilePath C:\Windows\Logs\choco-update-log.txt"'
# Set the trigger to be at any user logon
$trigger = New-ScheduledTaskTrigger -AtLogOn
# Specifies that Task Scheduler uses the Local Service account to run tasks, and that the Local Service account uses the Service Account logon. The command assigns the **ScheduledTaskPrincipal** object to the $STPrin variable.
$STPrin = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount
# Create the scheduled task
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "Update Choco all @ Login" -Description "Dit voert een choco update all commando uit in powershell tijdens inloggen van de user onder het system account." -Principal $STPrin
Save your script to a powershell file and upload it to Intune under Devices – Scripts. Use the following script settings.

Dependencies
Finally, make sure to set Chocolatey as a dependency for all your choco applications.
Thank you for the tutorial on this. However when I run one of these in intune, it fails with the following error, “The application was not detected after installation completed successfully (0x87D1041C)”.
Any ideas.
Please correct me if I am wrong here. I will delete this comment.
Its looks the author forgot to mention “command” in the CREATE THE INTUNE APP section
Installation Command should be:
powershell.exe -executionpolicy bypass command .\install.ps1
while it shows in the steps
powershell.exe -executionpolicy bypass .\install.ps1
Same applies for Uninstallation command
Just Automated it! Thanks for your Work !
Script with install/ userguide Below
https://github.com/dragoneyevip/IntuneChocolateyDeployment
Cool, Thanks!
Hello thankyou for this article!
I’m having difficulty getting applications to install.
From the company portal it says downloading and installing how it then says that it has failed. The only thing I believe I’ve changed from your article is the name of the file from install.ps1 to InstallApp.ps1
powershell.exe -executionpolicy bypass .\InstallApp.ps1 Firefox
powershell.exe -executionpolicy bypass .\InstallApp.ps1 Firefox – uninstall
Any ideas on where I’m going wrong?
Thats strange.
What if you run the detection script local on the computer, dus i give a valid output ?
Great guide, thanks for sharing!
Just a quick note that some applications have dependencies when installed with Chocolatey. As a result, they will display as two separate packages. For example:
7zip 21.7
7zip.install 21.7
To successfully and completely uninstall these, the chocolatey command should be:
choco uninstall $package -y –removedependencies
Thanks!
Hi, thanks for this blog.
I seem to notice a problem.
In the log I get the notification that it checks the versions, it downloads the new packages but the software version on the computer is still the older one.
It seems like everything is being downloaded but not installed.
I get the following:
first progress…% till 100
and then
the package x wants to run chocolateyinstall.ps1
Note: if you don’t run this script; the installation will fail
note: to confirm automatically next time, use ‘-y’ or consider:
choco feature enable -n allowGlobalConfirmation
I have no knowledge of this…do I need to add anything to the script our users don’t have admin rights.
Hi,
I would advice move to the new winget deployment method. This is already partly supported in intune as the new app deployment method.
You can find a lot of guides how to implement winget.