I have many different customers that basically need the same/similar base of win32 apps in Endpoint Manager. Entering the apps each time with the intunewin file, the name, the publisher, installation commands, etc. is unsatisfactory work. That's why I created a repository with a software list and a PowerShell script that automates the win32 app deployment.
An advanced version of the script can be found here: The "Intune Win32 Deployer" | scloud
I have stored the code of the PowerShell script, an example CSV including repository, on my GitHub: scloud/intune-win32-deployment at main FlorianSLZ/scloud (github.com)
(The upload script is in the folder "_UploadWin32App")
If you have problems with detection rules via script (New-IntuneWin32AppDetectionRuleScript), you can run the following fix.
precondition: Module is installed in the user context.
scloud/FIX_New-IntuneWin32AppDetectionRuleScript.ps1 at main FlorianSLZ/scloud (github.com)
The software list, a CSV file, consists of the most important parameters for the win32 apps. These are name, description, install/uninstall command, "runs as" and the dependency, if any. I deliberately omitted the recognition rule and also the compatibility. I use a custom script as a recognition rule and 64-bit and at least Windows 2004 for compatibility. I have had good experiences with these values. Of course, the list and the script could also be expanded so that they are set using the CSV .
Name;Beschreibung;install;uninstall;as;Dependeny 7-Zip;7-Zip ist ein Packprogramm;%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -command .\install.ps1;%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -command .\uninstall.ps1;systemCode language: CSS (css)
In my repository, each program is in a folder with the program name analogous to the software list. This folder contains the files required for the installation and uninstallation routine (usually instal.ps1 and uninstall.ps1), a check.ps1 (detection rule) and a PNG with the program name. In addition, I immediately created the intunewin file in order to be able to carry out manual uploads or updates from the repo.
The folder content of such a win32 app using the example 7-Zip looks like this:
I documented how my win32 applications are structured in a previous blog post: my take on win32 apps - Intune
The automation is based on PowerShell with the module "Microsoft.Graph.Intune" and "IntuneWin32App". You can find the script here.
The modules can be installed via PowerShell as admin:
Install-Module IntuneWin32App -Force Install-Module Microsoft.Graph.Intune -ForceCode language: PowerShell (powershell)
The structure and flow of the script is:
- Import module and read in initial variables (tenant prefix and software repository)
- Connection to tenant and login
- Reading in the CSV (Software-list.csv from the repository)
- Selection of the apps to be imported using a grid view (one or more possible)
- Creation and upload of the selected apps
- update connection
- Read Intunewin file
- Read display name
- Create detection rule (always check.ps1)
- Set system requirements (x64 and Windows 10 2004+)
- Set display image
- Upload the app with parameters
- Wait 15 seconds to avoid being blocked by Azure
(The waiting time prevents a blockage from Azure)
- If there is a dependency:
- Check whether this already exists in the MEM.
- If not, upload using the parameters from the CSV
- Add dependency
The application is in MEM with all variables, the icon and the dependency according to CSV.
App assignment (tip)
The script itself does not assign the applications to any group.
In order to be able to implement the assignment quickly and not have to open every app again in the MEM, I use the Intune for Education Portal. The portal has been specially developed for schools and is only advertised for them. However, it is possible to access the Intune for Education portal from any tenant using the correct URL: https://intuneeducation.portal.azure.com
- We can then use this to select a group and edit/select the assigned apps.
- The apps are then assigned with one click.
Attention: If an app is deselected in a group, it is automatically set to "uninstall".
It happens to me again and again that modules cannot be used properly because they conflict with another or a specific version. That's why I use a preconfigured sandbox for the deployments, which installs the current modules with a double click and starts the script.
I have more about this in the previous post "Pre-installed PowerShell modules in Windows Sandbox" written.
You can find the corresponding sandbox file including PowerShell in my GitHub:
scloud/Windows-Sandbox/win32-automated at main FlorianSLZ/scloud (github.com)
Pingback: Manage desktop shortcut(s) / icon with Intune | scloud
Pingback: Pre-installed PowerShell modules in Windows Sandbox | scloud
Thank you for allowing use of your script and csv template. I have used your script to upload multiple browser extensions into my tenants. One problem I have come across is that the script does not Start-Sleep, it just keeps going and I'm getting upload failures. Also the detection script.ps1 is not being uploaded at all, the apps will not get installed via the company portal because the detection is bugged and says that it's already installed. Have you had this issues yourself?
I look forward to your response.
Hi, unfortunately I noticed the same behavior in an upload this week.
It seems like something changed in the latest version of the Module. I'm already working on a fix. I'll keep you posted.
That's excellent. Thank you so much. I've Googled a bit trying to find answers and all I can find is that it seems to be that the check.ps1 script needs to be encoded in UTF8 format.
Did you find a solution on this?
Yes, the solution in Lewis's link worked.
If you want to automate it, you can use the following PowerShell command:
Thank you for a qucik fix! :).
But i am not sure where to run this script? Should it run on all my clients?
Yes, on the machine where you run the script. It is important, that you've installed the Modul in the user context.
Hallo Florian - dein Blog ist eine Inspiration ! Vielen Dank dafür! Deine Beispiele und Ansätze sind sehr wertvoll und erstklassig umsetzbar!
Wir steigen gerade um von chocolatey auf winget und ich hoffe, dass auch du schon bald neue Ideen zum App-Deployment mit winget zum Besten gibst.
Hallo Frank, vielen Dank für dein tolles Feedback.
Bezüglich Winget bin tatsächlich dran, da kannst du bald mit einem Beitrag rechnen 🙂