A bit more than a week ago the Intune Management Extension was added to Microsoft Intune to facilitate the ability to run PowerShell scripts on Windows 10 devices that are managed via MDM. That addition opens a whole new world for managing Windows 10 devices via MDM. Looking at app deployment specifically, this enables the administrator to look at something like Chocolatey for deploying packages. That would make the app deployment via Microsoft Intune suddenly flexible. In this blog post I’ll start with a little introduction about the Intune Management Extension and Chocolatey, followed by the configuration of a PowerShell script to install Chocolatey packages. I’ll end this post by looking at the end result.
Introduction
Let’s start with a short introduction about the awesome Intune Management Extension. The Intune Management Extension supplements the out-of-the-box MDM capabilities of Windows 10. It will be installed automatically on Windows 10 devices, that are managed via MDM, and it simply enables administrators to run PowerShell scripts on Windows 10 devices. Those PowerShell scripts can be used to provide additional capabilities that are missing from the out-of-the-box MDM functionality. The first scenario that the Intune Management Extension enabled, for me, is super easy app deployment via Chocolatey.
Chocolatey is a global PowerShell execution engine using the NuGet packaging infrastructure. Think of it as the ultimate automation tool for Windows. Chocolatey is a package manager that can also embed/wrap native installers and has functions for downloading and check-summing resources from the Internet. Super easy for installing application packages on Windows 10 devices.
Configuration
Now let’s have a look at the configuration. The configuration contains 3 steps. The first step is to create the required PowerShell script, the second step is to upload the PowerShell script to Intune and the third step is to assign the PowerShell script to an Azure AD group.
Step 1: Create PowerShell script
The first step is to create a PowerShell script that will check for the installation of Chocolatey, and that will install Chocolatey if it’s not yet installed. Once Chocolatey is installed the PowerShell script will install the required Chocolatey packages. Now let’s walk through the PowerShell script that I’ll use to do exactly that. The first thing that the script uses, are 2 variables. The first variable $ChocoPackages contains an array with the required Chocolatey packages and the second variable, $ChocoInstall, contains the default installation directory of Chocolatey (see below).
$ChocoPackages = @(“googlechrome”,”adobereader”,”notepadplusplus.install”,”7zip.install”)
$ChocoInstall = Join-Path ([System.Environment]::GetFolderPath(“CommonApplicationData”)) “Chocolatey\bin\choco.exe”
The second thing that the PowerShell script does is verifying the existence of the installation of Chocolatey. This is done by simply testing for the existence of choco.exe by using the $ChocoInstall variable. When choco.exe is not found, the online installation of Chocolatey will be triggered (see below).
if(!(Test-Path $ChocoInstall)) {
try {Invoke-Expression ((New-Object net.webclient).DownloadString(‘https://chocolatey.org/install.ps1’)) -ErrorAction Stop
}
catch {
Throw “Failed to install Chocolatey”
}
}
The third and last thing that the PowerShell script does is triggering the installation of the Chocolatey packages. This is done by running through the Chocolatey packages in the $ChocoPackages variable. For every package the installation will be triggered by using Chocolatey (see below).
foreach($Package in $ChocoPackages) {
try {
Invoke-Expression “cmd.exe /c $ChocoInstall Install $Package -y” -ErrorAction Stop
}
catch {
Throw “Failed to install $Package”
}
}
Now put these three pieces together in one script and save it as a PowerShell script (.ps1).
Step 2: Upload PowerShell script
The second step is to upload the created PowerShell script in Intune. To upload the PowerShell script, follow the next 5 steps.
1 | Open the Azure portal and navigate to Intune > Device configuration > PowerShell scripts; |
2 | On the Device configuration – PowerShell scripts blade, click Add script to open the Script Settings blade; |
3 |
On the Add PowerShell script blade, provide the following information and click Settings to open the Script Settings blade;
Note: The script must be less than 10 KB (ASCII) or 5 KB (Unicode). |
4 |
On the Script Settings blade, provide the following configuration and click OK to return to the PowerShell script blade;
Note: Configure Run the script using the logged on credentials to No means that the PowerShell script will run in SYSTEM context; |
5 | Back on the Add PowerShell script blade, click Create. |
Step 3: Assign PowerShell script
The third and last step is to assign the PowerShell script to an Azure AD group. To assign the PowerShell script, follow the next 5 steps.
1 | Open the Azure portal and navigate to Intune > Device configuration > PowerShell scripts; |
2 | On the Device configuration – PowerShell scripts blade, select the uploaded PowerShell script and click Assignments to open the {ScriptName} – Assignments blade; |
3 | On the {ScriptName} – Assignments blade, select the required Azure AD group and click Save. |
Note: Keep in mind that the Intune Management Extension synchronizes to Intune once every hour.
Result
Now let’s end this post by looking at the end result. Yes, I can show the installed applications, but it’s better for understanding the process to look at some log files. From an Intune Management Extension perspective, the most interesting log file is IntuneManagementExtension.log. That log file is located at C:\ProgramData\Microsoft\IntuneManagementExtension\Logs. Below is an example, in which I would like to highlight 2 sections:
- The first section shows that the first time a PowerShell script arrives on a device, as a policy, the complete script is shown in the log file;
- The second section clearly shows the configuration of the PowerShell script, by showing the configuration of the signature check and the context (as configured in step 2.4);
From a Chocolatey perspective, the most interesting log files are choco.log and choco.summary.log. These log files are located at C:\ProgramData\chocolatey\logs. To show the most interesting information, I would like to highlight 2 sections from the choco.summary.log below:
- The first section shows the detection of a Chocolatey packages that is already installed;
- The second section shows the installation of a Chocolatey package;
The nice thing about Chocolatey is that it already contains a lot of intelligence. A simple example of that is that it checks for the installation of the packages, before starting the installation. That enables me to use one script for installing the packages by simply adding new packages to the $ChocoPackages variable. When the script runs on the client, only the newly added packages will be installed.
Note: Keep in mind that you can also use Chocolatey for updating the installed packages.
More information
For more information about the Intune Management Extension and Chocolatey, please refer to the following articles:
- Manage PowerShell scripts in Intune for Windows 10 devices: https://docs.microsoft.com/en-us/intune/intune-management-extension
- The package manager for Windows: https://chocolatey.org/
Hoi Peter,
Met veel aandacht en plezier lees ik je blog dagelijks! Ik zou graag Chocolatey in onze omgeving toepassen dmv Intune en powershell; jouw voorbeeld script werkt lokaal volledig naar behoren, maar zodra ik het deploy naar de usergroup binnen Intune, werkt het niet. Andere scripts werken prima. De intune management extension log geeft aan dat het script error code 1 teruggeeft, en daar blijft het bij. vreemd?
Hi Joris,
I’m switching to English to help other readers understand. Exit code 1 is a pretty generic error, do you have some more details?
Also, keep in mind that the script should run in SYSTEM context.
Regards, Peter
I created a PS1 script with only the command , new-localuser -name Peter , in the log file i see ‘new-localuser’ is not recognized.
Second PS1 script with only , get-proces , runs fine.
Any idea’s why the first is failing ?
Script is set to run in SYSTEM context.
To be honest, I have no idea. I haven’t tested that specific example, but I can’t think of any reason why it would be problematic. Any more details in the Event Viewer or something like that?
Unfotunately nothing in eventvwr, only in the extension log file, cmdlet not recognized. Is the extension only capable of ps1.0 cmdlets or specific modules you know of?
Not to my knowledge, but I haven’t tested everything..
I paired this with another script I found to auto “choco upgrade all -y” every time you reboot the computer – https://chocolatey.org/packages/choco-upgrade-all-at-startup/2017.01.10
Thank you, Nigel!
That’s indeed one of the examples that I was referring to for auto-updating the installed apps.
Regards, Peter
Hi Peter,
I asked same question on oliver his blog and he has an answer. Its cause of extension runs in x86. Not spamming your blog but just you know, see https://oliverkieselbach.wordpress.com/2017/11/29/deep-dive-microsoft-intune-management-extension-powershell-scripts/
Thank you, Rkast!
That would make sense. If I have some time, I might devote a short post to that subject.
Regards, Peter
hi
I have multiple questions about this.
First, i’m so sorry but i’m french, so excuse my english.
2nd, i’m a noob, so excuse my questions 🙂
So i applied your script, and add some applications, but paint.net for example is never installed (but it said it is !). Do you know why ?
not directly related to this script, but
i also applied an xml to my start menu and taskbar, but, since my applications comes from chocolatey, or office install, when the xml is applied, all applications are not yet installed. So my taskbar or star menu doesn’t add these app when they are installed. Do you know why ? or how can i “update” my taskbar and start menu ? (i hope i’m clear :-))
Hi Daniel,
Did you check the installation log of Chocolatey for errors? That would be the first place to look, if the PowerShell script ended successfully.
Regards, Peter
hi thanks for the answer.
I did and didn’t see any errors.
also, do you know how to remove all shortcuts created by the scripts ? or to remove all shortcuts on the desktop ?
Daniel
Hi Dan,
Removing the shortcuts will be a scripted action.
Regards, Peter
Hi,
yes, but my question was : do you know how ?
i tried some examples that i found on the internet, but….not working.
Hi Dan,
The challenge is finding the location of the shortcut. Once you located that, it shouldn’t be that difficult to simply remove the file.
Regards, Peter
Does it update the applications ?
i saw that someone speaks about a script to update everythings:
https://chocolatey.org/packages/choco-upgrade-all-at-startup/2017.01.10
i try this one, but it doesn’t seem to work.
Nothing is updated….
Hi Dan,
This script will not trigger an update. For some apps that’s default behavior. You can indeed use a separate PowerShell script to trigger an update on the Chocolatey packages.
Regards, Peter
Hello,
Thank you for this article! I have the same issue as Joris. When I run the script locally everything seems to work perfectly. However when adding the script in Intune it fails.
Going through the logs it seems to be a syntax issue. It’s seems like the quotation marks are misinterpreted (in the logs some appear as questions marks).
Hi Michaël,
If you’re copying code from my blog directly, you indeed might run into issues with the quotes in the script.
Regards, Peter
Dear Peter
I tried this just today, running my script local on a pc works perfect, installation goes by fast and my personel can work.
If I try to push it in Intune to my virtual machine, it won’t work. It fails every time.
Any workaround? Or any idea what’s going on?
I execute in System context
Hi Andrew,
What is the result that you see in the logs?
Regards, Peter