IntuneBrew is a PowerShell-based tool that simplifies the process of uploading and managing macOS applications in Microsoft Intune. It automates the entire workflowβfrom downloading apps to uploading them to Intune with proper metadata and icons.
This project uses publicly available metadata from Homebrewβs JSON API. Homebrew is a registered trademark of its respective owners and is not affiliated with or endorsing this project.
- Watch the full walkthrough of the tool:
- Table of Contents
- π Latest Updates
- β¨ Features
- π Getting Started
- π Usage
- π§ Configuration
- π Version Management
- π οΈ Error Handling
- π€ Troubleshooting
- π€ Contributing
- Automated Workflows
- π License
- π Acknowledgments
- π Support
Last checked: 2026-01-22 14:27 UTC
| Application | Previous Version | New Version |
|---|---|---|
| Caffeine | 1.6.2 | 1.1.4 |
| Multi | 0.538.2 | 3.0.1 |
| Yaak | 2025.9.3 | 2026.1.0 |
| Canva | 1.119.0 | 1.120.0 |
| DataGrip | 2025.3.3 | 2025.3.4 |
| DbGate | 6.8.2 | 7.0.0 |
| 8x8_work | 8.29.1-3 | 8.30.2-10 |
| Caffeine | 1.6.2 | 1.1.4 |
| Multi | 0.538.2 | 3.0.1 |
| Pale Moon | 34.0.0 | 34.0.1 |
| Riverside Studio | 1.18.2 | 1.19.0 |
| Shapr3D | 5.1015.0.10234 | 26.0.0.10296 |
| Tribler | 8.2.3 | 8.3.1 |
| Cisco Jabber | 20251118100311 | 20260122074039 |
- π Automated app uploads to Microsoft Intune
- π¦ Supports both .dmg and .pkg files
- π Automatic version checking and updates
- πΌοΈ Automatic app icon integration
- π Progress tracking for large file uploads
- π Secure authentication with Microsoft Graph API
- π― Smart duplicate detection
- π« Bulk upload support
- π Automatic retry mechanism for failed uploads
- π Secure file encryption for uploads
- π Real-time progress monitoring
Note
Missing an app? Feel free to request additional app support by creating an issue!
First decide which authentication method you would like to use. There are currently the following methods implemented:
- System Managed Identity
- User Managed Identity
- ClientSecret & ClientID using App Registration
- Certificate based authentication
- Configuration File (for non-interactive/automated scenarios)
- Open your Automation Account and select Account Settings -> Identity.
- Turn Status on tab "System assigned" to "On".
- Add the following API permissions to your System Managed Identity using this PowerShell script: Microsoft Tech Community
- DeviceManagementApps.ReadWrite.All
- Open Entra admin center -> Applications -> Enterprise Applications. Change Filter "Application type" to "Managed Identities" and search for your Automation Account name. Open the entity.
- Verify that the right permissions are set to the Managed Identity in the Security -> Permissions tab.
- Create a new Variable in your Automation Account with the name "AuthenticationMethod" and value "SystemManagedIdentity" to use the System Managed Identity.
- Open Azure Portal and search for "Managed Identities".
- Click "Create" and select your Azure Subscription & Resource group. Choose your region and set a name for the identity.
- Open your Automation Account and select Account Settings -> Identity.
- Switch to tab "User assigned" and click "Add". Choose the previously created Managed Identity.
- Add the following API permissions to your System Managed Identity using this PowerShell script: Microsoft Tech Community
- DeviceManagementApps.ReadWrite.All
- Open Entra admin center -> Applications -> Enterprise Applications. Change Filter "Application type" to "Managed Identities" and search for your Automation Account name. Open the entity.
- Verify that the right permissions are set to the Managed Identity in the Security -> Permissions tab.
- Create a new Variable in your Automation Account with the name "AuthenticationMethod" and value "UserAssignedManagedIdentity" to use the User Assigned Managed Identity.
- Create a new App Registration in Azure
- Add the following API permissions:
- DeviceManagementApps.ReadWrite.All
- Update the parameters in the script with your Azure details.
- $appid = '' # App ID of the App Registration
- $tenantid = '' # Tenant ID of your EntraID
- $certThumbprint = '' # Thumbprint of the certificate associated with the App Registration
- Generate a self-signed certificate:
$cert = New-SelfSignedCertificate -Subject "CN=IntuneBrew" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256 -NotAfter (Get-Date).AddYears(2)- Export the certificate:
$pwd = ConvertTo-SecureString -String "YourPassword" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath "IntuneBrew.pfx" -Password $pwd- Upload to Azure App Registration:
- Go to your App Registration in Azure Portal
- Navigate to "Certificates & secrets"
- Upload the public key portion of your certificate
The -ConfigFile parameter enables non-interactive authentication, which is perfect for automation scenarios and macOS support. This method uses a JSON configuration file containing your authentication credentials.
- Create a configuration file based on one of these templates:
For Client Secret Authentication (clientSecret.json):
{
"authMethod": "ClientSecret",
"tenantId": "your-tenant-id",
"clientId": "your-app-registration-client-id",
"clientSecret": "your-client-secret"
}Example clientSecret.json with actual values:
{
"authMethod": "ClientSecret",
"tenantId": "12345678-1234-1234-1234-123456789012",
"clientId": "87654321-4321-4321-4321-210987654321",
"clientSecret": "xyx8Q~1234567890abcdefghijklmnopqrstuvwx"
}Important notes for clientSecret.json:
authMethod: Must be exactly "ClientSecret" (case-sensitive)tenantId: Your Azure AD tenant ID (GUID format)clientId: The Application (client) ID from your App RegistrationclientSecret: The secret value (not the secret ID) from your App Registration
Warning
- Store the clientSecret.json file securely and never commit it to version control
- Add
clientSecret.jsonto your.gitignorefile - Consider using environment variables or Azure Key Vault for production scenarios
- Client secrets expire - remember to rotate them before expiration
For Certificate Authentication (certificateThumbprint.json):
{
"authMethod": "Certificate",
"tenantId": "your-tenant-id",
"clientId": "your-app-registration-client-id",
"certificateThumbprint": "your-certificate-thumbprint"
}Example certificateThumbprint.json with actual values:
{
"authMethod": "Certificate",
"tenantId": "12345678-1234-1234-1234-123456789012",
"clientId": "87654321-4321-4321-4321-210987654321",
"certificateThumbprint": "1234567890ABCDEF1234567890ABCDEF12345678"
}Important notes for certificateThumbprint.json:
authMethod: Must be exactly "Certificate" (case-sensitive)tenantId: Your Azure AD tenant ID (GUID format)clientId: The Application (client) ID from your App RegistrationcertificateThumbprint: The thumbprint of the certificate uploaded to your App Registration (40 character hex string, no spaces or colons)- The certificate must be installed in the current user or local machine certificate store
-
Ensure your App Registration has the required permissions:
- DeviceManagementApps.ReadWrite.All
-
Use the configuration file with any IntuneBrew command:
# Update all apps non-interactively
.\IntuneBrew.ps1 -UpdateAll -ConfigFile "clientSecret.json"
# Upload specific apps with automation
.\IntuneBrew.ps1 -Upload "slack", "zoom" -ConfigFile "certificateThumbprint.json"Tip
The ConfigFile parameter is especially useful for:
- Automated deployments in CI/CD pipelines
- Scheduled tasks without user interaction
- Avoiding interactive authentication prompts
Using the -CopyAssignments switch with IntuneBrew.ps1 or creating a CopyAssignments Variable with Boolean Value true in your Azure Automation indicates that assignments from the existing app version should be copied to the new version.
The following automation variables can be configured in your Azure Automation Account:
| Variable | Type | Required | Default | Description |
|---|---|---|---|---|
AuthenticationMethod |
String | Yes | - | Authentication method: SystemManagedIdentity, UserAssignedManagedIdentity, or ClientSecret |
TenantId |
String | For ClientSecret | - | Azure AD Tenant ID |
AppId |
String | For ClientSecret/UserAssigned | - | Application/Client ID |
ClientSecret |
String | For ClientSecret | - | Client Secret value (not the ID) |
CopyAssignments |
Boolean | No | false | Copy assignments from old app version to new version |
UseExistingIntuneApp |
Boolean | No | false | Update existing apps instead of creating new ones (preserves assignments) |
MaxAppsPerRun |
Integer | No | 10 | Maximum apps to process per run (prevents memory issues in Azure sandbox) |
Notes:
- When
UseExistingIntuneAppistrue,CopyAssignmentsis automatically ignored (assignments are preserved on the existing app) MaxAppsPerRunhelps prevent the Azure Automation sandbox from suspending due to the 1GB memory limit
Apps are defined in JSON files with the following structure:
{
"name": "Application Name",
"description": "Application Description",
"version": "1.0.0",
"url": "https://download.url/app.dmg",
"bundleId": "com.example.app",
"homepage": "https://app.homepage.com",
"fileName": "app.dmg"
}IntuneBrew implements sophisticated version comparison logic:
- Handles various version formats (semantic versioning, build numbers)
- Supports complex version strings (e.g., "1.2.3,45678")
- Manages version-specific updates and rollbacks
- Provides clear version difference visualization
Version comparison rules:
- Main version numbers are compared first (1.2.3 vs 1.2.4)
- Build numbers are compared if main versions match
- Special handling for complex version strings with build identifiers
IntuneBrew includes robust error handling mechanisms:
-
Upload Retry Logic
- Automatic retry for failed uploads (up to 3 attempts)
- Exponential backoff between retries
- New SAS token generation for expired URLs
-
File Processing
- Temporary file cleanup
- Handle locked files
- Memory management for large files
-
Network Issues
- Connection timeout handling
- Bandwidth throttling
- Resume interrupted uploads
-
Authentication
- Token refresh handling
- Certificate expiration checks
- Fallback to interactive login
-
File Access Errors
- Ensure no other process is using the file
- Try deleting temporary files manually
- Restart the script
-
Upload Failures
- Check your internet connection
- Verify Azure AD permissions
- Ensure file sizes don't exceed Intune limits
-
Authentication Issues
- Verify your Azure AD credentials
- Check tenant ID configuration
- Ensure required permissions are granted
-
PowerShell 7 Command Not Found
If you're getting "IntuneBrew is not recognized as a name of a cmdlet, function, script file, or executable program" in PowerShell 7:
Step 1: Check your PATH environment variable
"Current PATH:" $env:PATH -split ';'
Step 2: Verify IntuneBrew installation location
$intuneBrewInfo = Get-InstalledScript -Name IntuneBrew -ErrorAction SilentlyContinue if ($intuneBrewInfo) { "Installed Location for IntuneBrew:" $intuneBrewInfo | Select-Object Name, Version, InstalledLocation } else { Write-Warning "IntuneBrew is not installed. Run: Install-Script IntuneBrew -Force" return }
Step 3: Add IntuneBrew to your PATH if needed
$scriptPath = $intuneBrewInfo.InstalledLocation if (-not ($env:PATH -split ';' | Where-Object { $_ -eq $scriptPath })) { Write-Host "`nπ Adding IntuneBrew script folder to PATH..." -ForegroundColor Yellow [Environment]::SetEnvironmentVariable("PATH", "$env:PATH;$scriptPath", [EnvironmentVariableTarget]::User) Write-Host "β Done. Restart PowerShell to use 'IntuneBrew' as a command." -ForegroundColor Green } else { Write-Host "β Script path is already in PATH." -ForegroundColor Green }
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
IntuneBrew uses a chain of GitHub Actions workflows to automate app management. Here's how the pipeline works:
App Request Approved
|
v
[1] Auto-Approve App Request
- Validates the app from Homebrew
- Adds app URL to collect_app_info.py
- Commits and pushes changes
|
v
[2] Build App Packages
- Collects app information from Homebrew
- Downloads and repackages apps (DMG/ZIP to PKG)
- Uploads packages to Azure Blob Storage
- Updates Apps/*.json with version info
- Generates supported_apps.json
- Updates README app count badge
|
+------------------+
| |
v v
[3a] Fetch App Icons [3b] Update Version Database
- Downloads missing - Syncs versions to Supabase
app icons from - Sends notifications to
Brandfetch API subscribed users
- Commits to Logos/ |
v
[4] Generate Uninstall Scripts
- Creates PowerShell uninstall
scripts for each app
- Commits to Uninstall Scripts/
| Workflow | Trigger | What It Does |
|---|---|---|
| Auto-Approve App Request | /.approve comment or auto-approved label |
Validates and adds new apps to the supported list |
| Build App Packages | Push to collect_app_info.py, daily schedule, or manual |
Downloads apps, creates PKG files, uploads to Azure |
| Fetch App Icons | After Build App Packages completes | Downloads missing app logos from Brandfetch |
| Update Version Database | After Build App Packages completes | Updates Supabase with version info, sends notifications |
| Generate Uninstall Scripts | After Update Version Database completes | Creates PowerShell uninstall scripts for Intune |
| Workflow | Schedule | Purpose |
|---|---|---|
| Categorize Apps | Daily or on app changes | Uses AI to categorize apps |
| Check App CVEs | Daily at 6 AM UTC | Scans for security vulnerabilities |
| QA App Installation | Manual only | Tests app installations on macOS |
| PSScriptAnalyzer | On IntuneBrew.ps1 changes | Lints PowerShell code |
| Send Weekly Reports | Mondays at 8 AM UTC | Sends fleet summary reports |
This project is licensed under the MIT License - see the LICENSE file for details.
- Thanks to all contributors who have helped shape IntuneBrew
- Microsoft Graph API documentation and community
- The PowerShell community for their invaluable resources
If you encounter any issues or have questions:
- Check the Issues page
- Review the troubleshooting guide
- Open a new issue if needed
Made with β€οΈ by Ugur Koc