Bulk uploading Win32 applications to Microsoft Intune can become time-consuming when you need to package applications, create Entra ID groups, configure detection rules, assign applications, and repeat the same process for dozens of applications.
This guide demonstrates how to automate the complete deployment process using PowerShell and the Microsoft Graph API. Instead of uploading every application manually, the automation reads configuration files, packages applications, uploads them to Intune, creates assignment groups, and assigns applications automatically.
By the end of this guide, you’ll understand how the solution works, what it supports, and how to customize it for your environment.
Win32 App Bulk Upload Workflow
The following workflow illustrates how the PowerShell automation deploys Win32 applications to Microsoft Intune. From reading the application folder to creating Microsoft Entra groups and assigning applications, each step is performed automatically to minimize manual effort and ensure consistent deployments.

The sections below explain each stage of the workflow in detail.
How the Automation Works
Read Application Folder
The script begins by scanning the specified application root folder and identifies each subfolder as a separate application. It verifies that the required installation files and configuration file are present before proceeding with the deployment.
Read Config.json
For each application, the script reads the Config.json file to retrieve deployment settings such as the application name, publisher, installation command, uninstall command, detection rule, assignment group, and other metadata. This allows every application to be deployed using its own configuration without modifying the PowerShell script.
Validate Configuration
Before packaging the application, the script validates the configuration to ensure all required properties are present and correctly formatted. If mandatory values are missing or invalid, the deployment for that application is skipped and the error is recorded in the log.
Create .intunewin Package
If the application package has not already been created, the script automatically packages the installer using the Microsoft Win32 Content Prep Tool. The resulting .intunewin file is then prepared for upload to Microsoft Intune.
Authenticate to Microsoft Graph
The script authenticates to Microsoft Graph using the configured Azure App Registration and required application permissions. Once authentication succeeds, all subsequent operations—including application creation, group management, and assignments—are performed through Microsoft Graph APIs.
Upload Win32 App
The script uploads the generated .intunewin package to Microsoft Intune and creates the Win32 application using the settings defined in the configuration file. It also configures application metadata, installation commands, detection rules, return codes, and other deployment properties automatically.
Create Microsoft Entra Group
If specified in the configuration, the script creates a Microsoft Entra security group for the application. This eliminates the need to manually create assignment groups for every application and ensures a consistent naming convention.
Assign Application
After the application and security group have been created, the script automatically assigns the Win32 application to the configured Microsoft Entra group. Assignment intent, such as Required or Available, is applied based on the values defined in the configuration.
Write Logs & Transcript
Throughout the deployment process, the script records detailed log entries and generates a PowerShell transcript. These logs help administrators verify successful deployments and quickly troubleshoot failures by identifying the exact step where an error occurred.
Prerequisites
- Active Microsoft Intune and Microsoft Entra administrator access.
- Entra App Registration with Microsoft Graph Application permissions
- Required PowerShell modules installed: (MALS & IntuneWin32 App)
- Download
IntuneWinAppUtil.exefrom Microsoft Win32 Content Prep Tool GitHub Repository. - Store application source files and
config.jsoninside individual app folders under theAppsdirectory. - Configure PowerShell execution policy if required:
Current Limitations
Currently Supported
- MSI Detection Rules
Planned for Future Release
- File, Registry, and Script Detection Rules
- Icon Upload Support
- Supersedence Support
- Requirement Rules Expansion
Folder Structure
The application installation source and configuration files need to be aligned as per the folder structure.
Intune_Win32App_AutoDeploy/
│
├── Apps/
│ ├── Notepad++ 8.9.1 x64/
│ │ ├── npp.8.9.1.Installer.x64.msi
│ │ └── config.json
│ │
│ └── 7Zip 24.09/
│ ├── 7z2409-x64.msi
│ └── config.json
│
├── IntuneWinAppUtil.exe
├── Intune_Win32App_AutoDeploy.ps1
└── Logs/

Config.json Parameters
The Config.json file controls how each Win32 application is packaged, uploaded, and assigned. Update the following properties to match your application’s deployment requirements.
| Parameter | Description | Required |
|---|---|---|
| DisplayName | Name displayed for the application in the Microsoft Intune admin center. | Yes |
| Description | Brief description of the application shown to administrators and users. | No |
| Publisher | Software publisher displayed in the application properties. | No |
| AppVersion | Version number of the application. Used for identification and reporting. | Yes |
| InstallerName | Name of the installer file located in the application folder. | Yes |
| InstallCmd | Silent installation command executed during deployment. | Yes |
| UninstallCmd | Silent uninstall command executed when removing the application. | Yes |
| CreateGroup | Specifies whether the script should automatically create a Microsoft Entra security group (Yes or No). | Yes |
| GroupName | Name of the Microsoft Entra security group created or used for application assignment. | Required if CreateGroup is Yes |
| AssignApp | Specifies whether the application should be automatically assigned after upload (Yes or No). | Yes |
| DetectionRules | Defines the detection method used by Intune to determine whether the application is installed. | Yes |
Detection Rule Parameters
| Parameter | Description |
|---|---|
| Type | Detection rule type. Currently, the script supports MSI detection. |
| Enabled | Enables or disables the detection rule. |
| ProductCode | MSI Product Code used to detect the installed application. |
| ProductVersionOperator | Comparison operator for the product version, such as equal, greaterThanOrEqual, or lessThan (depending on what your script supports). |
| ProductVersion | Version number compared against the installed MSI version. |
Note: The current version of the script supports MSI-based detection rules. Support for File, Registry, and PowerShell Script detection rules may be added in a future release.
Sample Config.json File
{
"DisplayName": "Notepad++ 8.9.1 x64",
"Description": "Notepad++",
"Publisher": "Notepad++",
"AppVersion": "8.9.1",
"InstallerName": "npp.8.9.1.Installer.x64.msi",
"InstallCmd": "msiexec /i npp.8.9.1.Installer.x64.msi /qn /norestart",
"UninstallCmd": "msiexec /x npp.8.9.1.Installer.x64.msi /qn /norestart",
"CreateGroup": "Yes",
"GroupName": "APP - Notepad++",
"AssignApp": "Yes",
"DetectionRules": [
{
"Type": "MSI",
"Enabled": true,
"ProductCode": "{7349B4F3-02E1-4234-A67A-FA85B33B67AF}",
"ProductVersionOperator": "equal",
"ProductVersion": "8.9.1"
}
]
}
Intune Automation Script Components
1. Configuration Validation
The script validates:
- Required JSON properties
- Empty values
- Installer file existence
- Folder name vs DisplayName mismatch
- Detection rule structure
Example validation logic:
if ($folderName -ne $Config.DisplayName) {
Write-Log @"
Folder name does not match DisplayName.
Folder Name : $folderName
DisplayName : $($Config.DisplayName)
"@ "ERROR"
$validationFailed = $true
}
This helps avoid deployment issues caused by copied configuration files. This helps in cleaner transcript logs and easier troubleshooting.
2. Centralized Logging
Instead of scattered Write-Host calls, the script uses a centralized logging function.
Example:
function Write-Log {
param(
[string]$Message,
[ValidateSet("INFO","WARN","ERROR","SUCCESS")]
[string]$Level = "INFO"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
switch ($Level) {
"INFO" { $color = "White" }
"WARN" { $color = "Yellow" }
"ERROR" { $color = "Red" }
"SUCCESS" { $color = "Green" }
}
Write-Host "[$timestamp] [$Level] $Message" `
-ForegroundColor $color
}
3. Service Principal Authentication
The script uses a Service Principal for unattended authentication.
Recommended permissions:
DeviceManagementApps.ReadWrite.All
DeviceManagementConfiguration.ReadWrite.All
Group.ReadWrite.All

Example authentication:
Connect-MSIntuneGraph ` -TenantID $tenantId ` -ClientID $clientId ` -ClientSecret $clientSecret
4. Automated Packaging
The script automatically creates .intunewin packages using IntuneWinAppUtil.exe.
Example:
Start-Process ` -FilePath $intuneUtilPath ` -ArgumentList $arguments ` -Wait ` -WindowStyle Hidden
5. Entra Group Creation
The script checks whether a group already exists before creating it.
Benefits:
- Prevents duplicate groups
- Safe re-execution
- Better bulk deployment experience
6. Assignment Handling
The script:
- Assigns apps automatically
- Prevents duplicate assignments
- Supports Available intent
Configuration Validation Mode
The script supports a validation-only mode. This is useful before large bulk deployments, as you can validate the configurations before bulk upload. Any issues identified with the configuration can be fixed before the bulk upload.
Example:
.\Intune_Win32App_AutoDeploy.ps1 -ValidateConfig
This mode:
- Validates JSON files
- Checks the installer’s existence
- Verifies folder naming
- Skips upload and assignment
Useful before large bulk deployments.
Running the Script
Normal Deployment
.\Intune_Win32App_AutoDeploy.ps1
Validation Only
.\Intune_Win32App_AutoDeploy.ps1 -ValidateConfig
Transcript Logging
The script automatically generates PowerShell transcripts.
Example:
Start-Transcript -Path ".\Logs\Deploy.log"
Logs help with:
- Troubleshooting
- Auditing
- Deployment history
Recommended Security Practice
Avoid storing secrets directly in the script. Instead, use environment variables:
$clientSecret = $env:INTUNE_CLIENT_SECRET
Set the user environment variable using the PowerShell command below. You need to run this with elevated PowerShell.
[System.Environment]::SetEnvironmentVariable( "INTUNE_CLIENT_SECRET", "YOUR_SECRET", [System.EnvironmentVariableTarget]::User)
Benefits of This Intune Automation
This framework helps:
- Reduce repetitive Intune administration
- Standardize application onboarding
- Improve deployment consistency
- Minimize manual errors
- Scale Win32 deployments
Especially useful for:
- Managed Service Provider (MSP) environments
- Large enterprise deployments
- Lab environments
- Application packaging teams
Future Enhancements
Planned improvements include:
- File and Registry detection rules
- Script detection support
- Icon uploads
- Supersedence support
- Requirement rule expansion
- Dependency support
- Retry logic improvements
Script Download
Download the complete Intune automation script from Techuisitive GitHub repository.
Related Posts
- Bulk Win32 App Deployment to Intune Using PowerShell and Microsoft Graph API
- Automating Intune Remediation Script Creation with Microsoft Graph API
- Bulk Export Entra ID Group Members with PowerShell & Microsoft Graph API
- How to Bulk Sync Intune Devices with Microsoft Graph
- Bulk Add Devices to Entra ID Group from CSV File
- How to Bulk Rename Windows Devices from Intune