# IntuneWin32App IntuneWin32App is a PowerShell module that automates the packaging, creation, and publishing of Win32 applications in Microsoft Intune. The module provides a comprehensive set of functions for managing the complete Win32 app lifecycle, from packaging source files into the required `.intunewin` format to deploying and assigning applications to users and devices through the Microsoft Graph API. As of version 1.5.0, the module implements native OAuth 2.0 authentication flows without any external dependencies, supporting interactive authentication with PKCE, device code flow, client credentials, and certificate-based authentication. The module offers full support for detection rules (MSI, file, registry, script-based), requirement rules including ARM64 architecture targeting, app dependencies and supersedence relationships, and flexible assignment configurations with filters. ## Authentication ### Connect-MSIntuneGraph Authenticates to Microsoft Graph API using various OAuth 2.0 flows. Supports interactive authentication with PKCE, device code flow for headless environments, client secret for automation, and certificate-based authentication for enterprise scenarios. ```powershell # Interactive authentication (default) - opens browser for user sign-in Connect-MSIntuneGraph -TenantID "contoso.onmicrosoft.com" -ClientID "12345678-1234-1234-1234-123456789012" # Device code flow - for remote sessions without browser access Connect-MSIntuneGraph -TenantID "contoso.onmicrosoft.com" -ClientID "12345678-1234-1234-1234-123456789012" -DeviceCode # Client secret flow - for CI/CD pipelines and automation $ClientSecret = "your-client-secret-here" Connect-MSIntuneGraph -TenantID "contoso.onmicrosoft.com" -ClientID "12345678-1234-1234-1234-123456789012" -ClientSecret $ClientSecret # Certificate-based authentication - for enterprise service principals $Cert = Get-Item -Path "Cert:\CurrentUser\My\THUMBPRINT123" Connect-MSIntuneGraph -TenantID "contoso.onmicrosoft.com" -ClientID "12345678-1234-1234-1234-123456789012" -ClientCert $Cert # Custom scopes - when you need specific permissions only $CustomScopes = @("DeviceManagementApps.ReadWrite.All", "offline_access") Connect-MSIntuneGraph -TenantID "contoso.onmicrosoft.com" -ClientID "12345678-1234-1234-1234-123456789012" -Scopes $CustomScopes # Token refresh - silently renew an existing token Connect-MSIntuneGraph -TenantID "contoso.onmicrosoft.com" -ClientID "12345678-1234-1234-1234-123456789012" -Refresh ``` ## Packaging Applications ### New-IntuneWin32AppPackage Packages application source files into the required `.intunewin` encrypted container format using Microsoft's IntuneWinAppUtil.exe. The utility is automatically downloaded if not present. ```powershell # Package an MSI installer $SourceFolder = "C:\Win32Apps\Source\7-Zip" $SetupFile = "7z2301-x64.msi" $OutputFolder = "C:\Win32Apps\Output" $Package = New-IntuneWin32AppPackage -SourceFolder $SourceFolder -SetupFile $SetupFile -OutputFolder $OutputFolder -Verbose # Package with Force to overwrite existing file New-IntuneWin32AppPackage -SourceFolder "C:\Apps\MyApp" -SetupFile "setup.exe" -OutputFolder "C:\Output" -Force -Verbose # Use custom IntuneWinAppUtil.exe path New-IntuneWin32AppPackage -SourceFolder "C:\Apps\MyApp" -SetupFile "install.msi" -OutputFolder "C:\Output" -IntuneWinAppUtilPath "D:\Tools\IntuneWinAppUtil.exe" # Output contains package details # $Package.Name - Application name # $Package.FileName - Packaged file name # $Package.SetupFile - Original setup file # $Package.Path - Full path to .intunewin file ``` ### Get-IntuneWin32AppMetaData Extracts metadata from an existing `.intunewin` package file, including MSI information, encryption details, and file sizes. ```powershell # Get metadata from packaged file $MetaData = Get-IntuneWin32AppMetaData -FilePath "C:\Win32Apps\Output\7z2301-x64.intunewin" # Access MSI-specific information $ProductCode = $MetaData.ApplicationInfo.MsiInfo.MsiProductCode $ProductVersion = $MetaData.ApplicationInfo.MsiInfo.MsiProductVersion $Publisher = $MetaData.ApplicationInfo.MsiInfo.MsiPublisher # Access general application info $AppName = $MetaData.ApplicationInfo.Name $SetupFile = $MetaData.ApplicationInfo.SetupFile $UnencryptedSize = $MetaData.ApplicationInfo.UnencryptedContentSize ``` ### Expand-IntuneWin32AppPackage Decompresses and decrypts a `.intunewin` package file to extract the original source files. ```powershell # Expand packaged file to view contents Expand-IntuneWin32AppPackage -FilePath "C:\Win32Apps\Output\7z2301-x64.intunewin" -Force -Verbose # Extracted files will be placed in the same directory as the source file ``` ## Managing Win32 Apps ### Get-IntuneWin32App Retrieves Win32 applications from Microsoft Intune by display name, ID, or returns all Win32 apps. ```powershell # Get all Win32 apps in the tenant $AllApps = Get-IntuneWin32App -Verbose # Search by display name (wildcard search) $Apps = Get-IntuneWin32App -DisplayName "7-zip" -Verbose # Get specific app by ID $App = Get-IntuneWin32App -ID "12345678-1234-1234-1234-123456789012" -Verbose # List all apps and filter $AllApps = Get-IntuneWin32App $FilteredApps = $AllApps | Where-Object { $_.publisher -eq "Microsoft" } ``` ### Add-IntuneWin32App Creates a new Win32 application in Microsoft Intune with full support for MSI and EXE/script-based installations. ```powershell # Create MSI-based Win32 app with detection rule $IntuneWinFile = "C:\Win32Apps\Output\7z2301-x64.intunewin" $MetaData = Get-IntuneWin32AppMetaData -FilePath $IntuneWinFile # Create requirement rule with ARM64 support $RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "AllWithARM64" -MinimumSupportedWindowsRelease "W10_21H2" # Create MSI detection rule $DetectionRule = New-IntuneWin32AppDetectionRuleMSI -ProductCode $MetaData.ApplicationInfo.MsiInfo.MsiProductCode -ProductVersionOperator "greaterThanOrEqual" -ProductVersion $MetaData.ApplicationInfo.MsiInfo.MsiProductVersion # Create icon $Icon = New-IntuneWin32AppIcon -FilePath "C:\Icons\7zip.png" # Create custom return code $ReturnCode = New-IntuneWin32AppReturnCode -ReturnCode 1337 -Type "retry" # Add the Win32 app $Win32App = Add-IntuneWin32App -FilePath $IntuneWinFile ` -DisplayName "7-Zip 23.01" ` -Description "7-Zip file archiver" ` -Publisher "Igor Pavlov" ` -AppVersion "23.01" ` -InstallExperience "system" ` -RestartBehavior "suppress" ` -DetectionRule $DetectionRule ` -RequirementRule $RequirementRule ` -ReturnCode $ReturnCode ` -Icon $Icon ` -CategoryName "Productivity" ` -MaximumInstallationTimeInMinutes 30 ` -Verbose # Create EXE-based Win32 app with script detection $ScriptDetection = New-IntuneWin32AppDetectionRuleScript -ScriptFile "C:\Scripts\Detect-App.ps1" -EnforceSignatureCheck $false -RunAs32Bit $false $Win32App = Add-IntuneWin32App -FilePath "C:\Output\MyApp.intunewin" ` -DisplayName "My Custom App 1.0" ` -Description "Custom application deployment" ` -Publisher "Contoso" ` -InstallCommandLine "powershell.exe -ExecutionPolicy Bypass -File .\Install.ps1" ` -UninstallCommandLine "powershell.exe -ExecutionPolicy Bypass -File .\Uninstall.ps1" ` -InstallExperience "system" ` -RestartBehavior "basedOnReturnCode" ` -DetectionRule $ScriptDetection ` -RequirementRule $RequirementRule ` -AllowAvailableUninstall ` -Verbose ``` ### Set-IntuneWin32App Updates properties of an existing Win32 application including detection rules, icons, commands, and requirement rules. ```powershell # Get existing app $App = Get-IntuneWin32App -DisplayName "7-Zip" | Select-Object -First 1 # Update basic properties Set-IntuneWin32App -ID $App.id ` -DisplayName "7-Zip File Archiver" ` -Description "Updated description for 7-Zip" ` -AppVersion "23.02" ` -Publisher "Igor Pavlov" ` -Owner "IT Department" ` -Notes "Updated via automation" ` -Verbose # Update detection rule $NewDetectionRule = New-IntuneWin32AppDetectionRuleFile -Existence ` -Path "C:\Program Files\7-Zip" ` -FileOrFolderName "7z.exe" ` -DetectionType "exists" Set-IntuneWin32App -ID $App.id -DetectionRule $NewDetectionRule -Verbose # Update icon $NewIcon = New-IntuneWin32AppIcon -FilePath "C:\Icons\new-icon.png" Set-IntuneWin32App -ID $App.id -Icon $NewIcon -Verbose # Update install commands and restart behavior Set-IntuneWin32App -ID $App.id ` -InstallCommandLine "msiexec /i setup.msi /quiet /norestart" ` -UninstallCommandLine "msiexec /x {PRODUCT-CODE} /quiet" ` -RestartBehavior "suppress" ` -MaximumInstallationTimeInMinutes 60 ` -Verbose # Update requirement rule for ARM64 support $NewRequirementRule = New-IntuneWin32AppRequirementRule -Architecture "AllWithARM64" -MinimumSupportedWindowsRelease "W11_22H2" Set-IntuneWin32App -ID $App.id -RequirementRule $NewRequirementRule -Verbose ``` ### Remove-IntuneWin32App Deletes a Win32 application from Microsoft Intune. ```powershell # Remove by display name Remove-IntuneWin32App -DisplayName "Old Application" -Verbose # Remove by ID Remove-IntuneWin32App -ID "12345678-1234-1234-1234-123456789012" -Verbose ``` ## Detection Rules ### New-IntuneWin32AppDetectionRuleMSI Creates an MSI product code-based detection rule for MSI installations. ```powershell # Basic MSI detection $DetectionRule = New-IntuneWin32AppDetectionRuleMSI -ProductCode "{12345678-1234-1234-1234-123456789012}" # MSI detection with version comparison $DetectionRule = New-IntuneWin32AppDetectionRuleMSI ` -ProductCode "{12345678-1234-1234-1234-123456789012}" ` -ProductVersionOperator "greaterThanOrEqual" ` -ProductVersion "23.01.0" # Get product code from MSI file $ProductCode = Get-MSIMetaData -Path "C:\Installers\app.msi" -Property "ProductCode" $DetectionRule = New-IntuneWin32AppDetectionRuleMSI -ProductCode $ProductCode.Trim() ``` ### New-IntuneWin32AppDetectionRuleFile Creates a file or folder-based detection rule with options for existence, version, date, or size checks. ```powershell # Detect if file exists $DetectionRule = New-IntuneWin32AppDetectionRuleFile -Existence ` -Path "C:\Program Files\MyApp" ` -FileOrFolderName "app.exe" ` -DetectionType "exists" # Detect file version $DetectionRule = New-IntuneWin32AppDetectionRuleFile -Version ` -Path "C:\Program Files\MyApp" ` -FileOrFolderName "app.exe" ` -Operator "greaterThanOrEqual" ` -VersionValue "2.0.0.0" # Detect file size (in MB) $DetectionRule = New-IntuneWin32AppDetectionRuleFile -Size ` -Path "C:\Program Files\MyApp" ` -FileOrFolderName "data.db" ` -Operator "greaterThan" ` -SizeInMBValue "100" # Detect file modified date $DetectionRule = New-IntuneWin32AppDetectionRuleFile -DateModified ` -Path "C:\Program Files\MyApp" ` -FileOrFolderName "config.xml" ` -Operator "greaterThan" ` -DateTimeValue (Get-Date "2024-01-01") # Check 32-bit location on 64-bit systems $DetectionRule = New-IntuneWin32AppDetectionRuleFile -Existence ` -Path "C:\Program Files (x86)\MyApp" ` -FileOrFolderName "app.exe" ` -DetectionType "exists" ` -Check32BitOn64System $true ``` ### New-IntuneWin32AppDetectionRuleRegistry Creates a registry-based detection rule for checking registry keys or values. ```powershell # Detect if registry key exists $DetectionRule = New-IntuneWin32AppDetectionRuleRegistry -Existence ` -KeyPath "HKEY_LOCAL_MACHINE\SOFTWARE\MyApp" ` -DetectionType "exists" # Detect registry string value $DetectionRule = New-IntuneWin32AppDetectionRuleRegistry -StringComparison ` -KeyPath "HKEY_LOCAL_MACHINE\SOFTWARE\MyApp" ` -ValueName "Version" ` -Operator "equal" ` -Value "2.0.0" # Detect registry version value $DetectionRule = New-IntuneWin32AppDetectionRuleRegistry -VersionComparison ` -KeyPath "HKEY_LOCAL_MACHINE\SOFTWARE\MyApp" ` -ValueName "InstalledVersion" ` -Operator "greaterThanOrEqual" ` -Value "1.5.0.0" # Detect integer value $DetectionRule = New-IntuneWin32AppDetectionRuleRegistry -IntegerComparison ` -KeyPath "HKEY_LOCAL_MACHINE\SOFTWARE\MyApp" ` -ValueName "BuildNumber" ` -Operator "greaterThan" ` -Value 1000 ``` ### New-IntuneWin32AppDetectionRuleScript Creates a PowerShell script-based detection rule for custom detection logic. ```powershell # Create script detection rule $DetectionRule = New-IntuneWin32AppDetectionRuleScript ` -ScriptFile "C:\Scripts\Detect-MyApp.ps1" ` -EnforceSignatureCheck $false ` -RunAs32Bit $false # Example detection script content (Detect-MyApp.ps1): # if (Test-Path "C:\Program Files\MyApp\app.exe") { # $version = (Get-Item "C:\Program Files\MyApp\app.exe").VersionInfo.FileVersion # if ([version]$version -ge [version]"2.0.0.0") { # Write-Output "Detected" # exit 0 # } # } # exit 1 ``` ## Requirement Rules ### New-IntuneWin32AppRequirementRule Creates the base requirement rule specifying architecture and minimum OS version. ```powershell # Intel/AMD 64-bit only $RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "x64" -MinimumSupportedWindowsRelease "W10_21H2" # Both 32-bit and 64-bit Intel/AMD $RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "x64x86" -MinimumSupportedWindowsRelease "W10_20H2" # ARM64 only $RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "arm64" -MinimumSupportedWindowsRelease "W11_22H2" # All architectures including ARM64 (universal) $RequirementRule = New-IntuneWin32AppRequirementRule -Architecture "AllWithARM64" -MinimumSupportedWindowsRelease "W11_21H2" # With hardware requirements $RequirementRule = New-IntuneWin32AppRequirementRule ` -Architecture "x64" ` -MinimumSupportedWindowsRelease "W10_21H2" ` -MinimumFreeDiskSpaceInMB 5120 ` -MinimumMemoryInMB 4096 ` -MinimumNumberOfProcessors 2 ` -MinimumCPUSpeedInMHz 1000 ``` ## Assignments ### Add-IntuneWin32AppAssignmentGroup Adds a group-based assignment to a Win32 app with support for include/exclude, filters, and restart settings. ```powershell # Required assignment for a group $App = Get-IntuneWin32App -DisplayName "7-Zip" | Select-Object -First 1 Add-IntuneWin32AppAssignmentGroup -Include ` -ID $App.id ` -GroupID "12345678-1234-1234-1234-123456789012" ` -Intent "required" ` -Notification "showAll" ` -Verbose # Available assignment with deadline Add-IntuneWin32AppAssignmentGroup -Include ` -ID $App.id ` -GroupID "12345678-1234-1234-1234-123456789012" ` -Intent "available" ` -Notification "showReboot" ` -AvailableTime (Get-Date) ` -DeadlineTime (Get-Date).AddDays(7) ` -UseLocalTime $true ` -Verbose # Exclude a group from assignment Add-IntuneWin32AppAssignmentGroup -Exclude ` -ID $App.id ` -GroupID "12345678-1234-1234-1234-123456789012" ` -Intent "required" ` -Verbose # Assignment with filter Add-IntuneWin32AppAssignmentGroup -Include ` -ID $App.id ` -GroupID "12345678-1234-1234-1234-123456789012" ` -Intent "required" ` -FilterName "Windows 11 Devices" ` -FilterMode "Include" ` -Verbose # Assignment with restart grace period Add-IntuneWin32AppAssignmentGroup -Include ` -ID $App.id ` -GroupID "12345678-1234-1234-1234-123456789012" ` -Intent "required" ` -EnableRestartGracePeriod $true ` -RestartGracePeriod 1440 ` -RestartCountDownDisplay 15 ` -RestartNotificationSnooze 240 ` -Verbose # Auto-update superseded apps (available intent only) Add-IntuneWin32AppAssignmentGroup -Include ` -ID $App.id ` -GroupID "12345678-1234-1234-1234-123456789012" ` -Intent "available" ` -AutoUpdateSupersededApps "enabled" ` -Verbose ``` ### Add-IntuneWin32AppAssignmentAllUsers Adds an assignment targeting all users in the tenant. ```powershell $App = Get-IntuneWin32App -DisplayName "7-Zip" | Select-Object -First 1 # Available to all users Add-IntuneWin32AppAssignmentAllUsers -ID $App.id -Intent "available" -Notification "showAll" -Verbose # Required for all users with deadline Add-IntuneWin32AppAssignmentAllUsers -ID $App.id ` -Intent "required" ` -Notification "hideAll" ` -DeadlineTime (Get-Date).AddDays(3) ` -Verbose ``` ### Add-IntuneWin32AppAssignmentAllDevices Adds an assignment targeting all devices in the tenant. ```powershell $App = Get-IntuneWin32App -DisplayName "7-Zip" | Select-Object -First 1 # Required for all devices Add-IntuneWin32AppAssignmentAllDevices -ID $App.id -Intent "required" -Notification "showReboot" -Verbose # Available for all devices with filter Add-IntuneWin32AppAssignmentAllDevices -ID $App.id ` -Intent "available" ` -Notification "showAll" ` -FilterName "Corporate Devices" ` -FilterMode "Include" ` -Verbose ``` ### Get-IntuneWin32AppAssignment Retrieves assignments for a Win32 app. ```powershell $App = Get-IntuneWin32App -DisplayName "7-Zip" | Select-Object -First 1 # Get all assignments for an app $Assignments = Get-IntuneWin32AppAssignment -ID $App.id -Verbose # Get assignments for a specific group $GroupAssignments = Get-IntuneWin32AppAssignment -GroupName "IT Department" -Verbose ``` ### Remove-IntuneWin32AppAssignment Removes assignments from a Win32 app. ```powershell $App = Get-IntuneWin32App -DisplayName "7-Zip" | Select-Object -First 1 # Remove specific assignment by ID Remove-IntuneWin32AppAssignment -ID $App.id -AssignmentID "assignment-guid-here" -Verbose # Remove all 'All Users' assignments Remove-IntuneWin32AppAssignmentAllUsers -ID $App.id -Verbose # Remove all 'All Devices' assignments Remove-IntuneWin32AppAssignmentAllDevices -ID $App.id -Verbose # Remove specific group assignment Remove-IntuneWin32AppAssignmentGroup -ID $App.id -GroupID "group-guid-here" -Verbose ``` ## Dependencies and Supersedence ### Add-IntuneWin32AppDependency Adds dependency relationships between Win32 apps. ```powershell $ParentApp = Get-IntuneWin32App -DisplayName "My Application" | Select-Object -First 1 $DependencyApp = Get-IntuneWin32App -DisplayName "Visual C++ Runtime" | Select-Object -First 1 # Create dependency object $Dependency = New-IntuneWin32AppDependency -ID $DependencyApp.id -DependencyType "AutoInstall" # Add dependency to parent app Add-IntuneWin32AppDependency -ID $ParentApp.id -Dependency $Dependency -Verbose ``` ### Add-IntuneWin32AppSupersedence Configures app supersedence relationships for updating or replacing existing apps. ```powershell $NewApp = Get-IntuneWin32App -DisplayName "App v2.0" | Select-Object -First 1 $OldApp = Get-IntuneWin32App -DisplayName "App v1.0" | Select-Object -First 1 # Create supersedence object (update mode) $Supersedence = New-IntuneWin32AppSupersedence -ID $OldApp.id -SupersedenceType "Update" # Add supersedence to new app Add-IntuneWin32AppSupersedence -ID $NewApp.id -Supersedence $Supersedence -Verbose ``` ## Complete Workflow Example ```powershell # Full automated Win32 app deployment workflow # Authenticate Connect-MSIntuneGraph -TenantID "contoso.onmicrosoft.com" -ClientID "your-client-id" # Package application $Package = New-IntuneWin32AppPackage ` -SourceFolder "C:\Apps\7-Zip" ` -SetupFile "7z2301-x64.msi" ` -OutputFolder "C:\Output" ` -Force -Verbose # Get metadata $MetaData = Get-IntuneWin32AppMetaData -FilePath $Package.Path # Create detection rule $DetectionRule = New-IntuneWin32AppDetectionRuleMSI ` -ProductCode $MetaData.ApplicationInfo.MsiInfo.MsiProductCode ` -ProductVersionOperator "greaterThanOrEqual" ` -ProductVersion $MetaData.ApplicationInfo.MsiInfo.MsiProductVersion # Create requirement rule $RequirementRule = New-IntuneWin32AppRequirementRule ` -Architecture "AllWithARM64" ` -MinimumSupportedWindowsRelease "W10_21H2" # Create icon $Icon = New-IntuneWin32AppIcon -FilePath "C:\Icons\7zip.png" # Create Win32 app $Win32App = Add-IntuneWin32App ` -FilePath $Package.Path ` -DisplayName "7-Zip $($MetaData.ApplicationInfo.MsiInfo.MsiProductVersion)" ` -Description "7-Zip file archiver" ` -Publisher $MetaData.ApplicationInfo.MsiInfo.MsiPublisher ` -InstallExperience "system" ` -RestartBehavior "suppress" ` -DetectionRule $DetectionRule ` -RequirementRule $RequirementRule ` -Icon $Icon ` -Verbose # Assign to all users as available Add-IntuneWin32AppAssignmentAllUsers -ID $Win32App.id -Intent "available" -Notification "showAll" -Verbose # Assign as required to specific group Add-IntuneWin32AppAssignmentGroup -Include ` -ID $Win32App.id ` -GroupID "pilot-users-group-id" ` -Intent "required" ` -Notification "showReboot" ` -DeadlineTime (Get-Date).AddDays(7) ` -Verbose Write-Output "Successfully deployed: $($Win32App.displayName)" ``` ## Summary IntuneWin32App provides a comprehensive PowerShell solution for managing the entire Win32 application lifecycle in Microsoft Intune. The module excels at automating repetitive deployment tasks such as packaging applications, creating apps with proper detection and requirement rules, and configuring assignments with filters and deadlines. Its native OAuth 2.0 implementation makes it suitable for both interactive administration and automated CI/CD pipelines without requiring external authentication modules. Common integration patterns include automated app packaging and deployment pipelines triggered by new software releases, bulk app management scripts for tenant migrations, and scheduled tasks for keeping applications up-to-date across the organization. The module's support for ARM64 architecture, assignment filters, and app supersedence makes it well-suited for modern Windows endpoint management scenarios where organizations need to maintain consistent application deployments across diverse device fleets.