Skip to content
February 27, 2026 • Mid-Level (3-5 years) Script Drop

PowerShell Win32 App Installer Scripts

By Last updated

Essential PowerShell scripts for installing and managing Win32 apps in Intune. Automate your app deployment workflow.

Waitlist · planned for Dec 1, 2026

The Win32 Deployment Doctor

Read-only checks for Intune Win32 app deployments: a tenant audit of detection rules, return codes, dependencies and supersedence, plus an on-device IME log diagnostic. Join the waitlist and we'll email you when it ships. What it checks

We'll email you when it ships. Unsubscribe anytime. Privacy

Step-by-step guide

PowerShell Win32 App Installer Scripts

Deploying Win32 apps in Intune is powerful but can be tricky. These scripts will help you package, install, and troubleshoot Win32 applications like a pro.

Script 1: Silent Install Wrapper

Every Win32 app needs a silent install. This wrapper handles the most common scenarios:

<#
.SYNOPSIS
    Universal silent installer wrapper for Win32 apps
    
.PARAMETER InstallerPath
    Full path to the installer file
    
.PARAMETER Arguments
    Silent install arguments
    
.PARAMETER ExpectedExitCode
    Expected exit code on success (default: 0)
#>
param(
    [Parameter(Mandatory=$true)]
    [string]$InstallerPath,
    
    [Parameter(Mandatory=$false)]
    [string]$Arguments = "/S",
    
    [Parameter(Mandatory=$false)]
    [int]$ExpectedExitCode = 0
)

$ErrorActionPreference = "Stop"
$LogFile = "$env:TEMP\Win32Install_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"

function Write-Log {
    param([string]$Message)
    $Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
    $LogMessage = "[$Timestamp] $Message"
    Write-Host $LogMessage
    Add-Content -Path $LogFile -Value $LogMessage
}

Write-Log "Starting installation: $InstallerPath"
Write-Log "Arguments: $Arguments"

try {
    $Process = Start-Process -FilePath $InstallerPath -ArgumentList $Arguments -Wait -PassThru -NoNewWindow
    
    if ($Process.ExitCode -eq $ExpectedExitCode) {
        Write-Log "SUCCESS: Installation completed with exit code $($Process.ExitCode)"
        exit 0
    } else {
        Write-Log "WARNING: Installation completed with unexpected exit code $($Process.ExitCode)"
        exit $Process.ExitCode
    }
}
catch {
    Write-Log "ERROR: $($_.Exception.Message)"
    exit 1
}

Usage:

.\Install-App.ps1 -InstallerPath "C:\Apps\7zip\7zip-x64.msi" -Arguments "/quiet /norestart"

Script 2: Detection Rule Generator

Create detection rules for your Win32 apps automatically:

<#
.SYNOPSIS
    Generate Intune detection rules for Win32 apps
#>

param(
    [Parameter(Mandatory=$true)]
    [string]$AppName,
    
    [Parameter(Mandatory=$false)]
    [ValidateSet("File", "Registry", "MSI")]
    [string]$DetectionType = "File",
    
    [Parameter(Mandatory=$true)]
    [string]$DetectionPath,
    
    [Parameter(Mandatory=$false)]
    [string]$DetectionVersion
)

$Rule = @{
    "@odata.type" = "#microsoft.graph.win32LobAppDetectionRule"
    ruleType = switch ($DetectionType) {
        "File" { "file" }
        "Registry" { "registry" }
        "MSI" { "productVersion" }
    }
    path = $DetectionPath
    fileOrFolderName = Split-Path $DetectionPath -Leaf
}

if ($DetectionVersion) {
    $Rule["version"] = $DetectionVersion
    $Rule["operator"] = "greaterThanOrEqual"
}

$DetectionRule = @{
    rules = @($Rule)
} | ConvertTo-Json -Depth 5

Write-Output $DetectionRule

# Save to file for Intune Win32 import
$DetectionRule | Out-File -FilePath ".\$AppName-detection-rule.json"
Write-Host "Detection rule saved to .\$AppName-detection-rule.json"

Script 3: Pre-Install System Check

Check prerequisites before installing:

<#
.SYNOPSIS
    Pre-installation system checks for Win32 apps
#>

$ErrorActionPreference = "Continue"

Write-Host "=== System Prerequisites Check ===" -ForegroundColor Cyan

$Checks = @{
    "Disk Space (C:)" = {
        $Drive = Get-PSDrive -Name C
        [math]::Round($Drive.Free / 1GB, 2)
    }
    "OS Version" = {
        (Get-CimInstance Win32_OperatingSystem).Caption
    }
    "Architecture" = {
        $env:PROCESSOR_ARCHITECTURE
    }
    "Intune Agent Version" = {
        (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\IntuneAgent" -ErrorAction SilentlyContinue).Version
    }
    "PowerShell Version" = {
        $PSVersionTable.PSVersion.ToString()
    }
    "Free RAM (GB)" = {
        [math]::Round((Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory / 1MB, 2)
    }
}

$AllPassed = $true

foreach ($Check in $Checks.GetEnumerator()) {
    $Result = & $Check.Value
    $Status = if ($Result) { "✓ PASS" } else { "✗ FAIL" }
    $Color = if ($Result) { "Green" } else { "Red" }
    
    Write-Host "$($Check.Key): $Result - $Status" -ForegroundColor $Color
    
    if (-not $Result -and $Check.Key -ne "Free RAM (GB)") {
        $AllPassed = $false
    }
}

if ($AllPassed) {
    Write-Host "`nAll checks passed!" -ForegroundColor Green
    exit 0
} else {
    Write-Host "`nSome checks failed!" -ForegroundColor Red
    exit 1
}

Script 4: Uninstall Legacy App

Clean up old versions before installing new:

<#
.SYNOPSIS
    Uninstall existing versions of an application
#>
param(
    [Parameter(Mandatory=$true)]
    [string]$AppName,
    
    [Parameter(Mandatory=$false)]
    [string[]]$UninstallStrings
)

$ErrorActionPreference = "Continue"

Write-Host "Searching for existing $AppName installations..." -ForegroundColor Yellow

$InstalledApps = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*,
    HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue

$FoundApps = $InstalledApps | Where-Object { $_.DisplayName -like "*$AppName*" }

if ($FoundApps) {
    foreach ($App in $FoundApps) {
        Write-Host "Found: $($App.DisplayName) - $($App.Version)"
        
        if ($App.UninstallString) {
            Write-Host "Uninstalling..."
            
            $UninstallString = $App.UninstallString
            
            # Handle different uninstall formats
            if ($UninstallString -match "msiexec") {
                $UninstallString += " /qn /norestart"
            }
            
            Start-Process -FilePath "cmd.exe" -ArgumentList "/c $($UninstallString)" -Wait -NoNewWindow
            Write-Host "Uninstalled successfully"
        }
    }
} else {
    Write-Host "No existing installations found" -ForegroundColor Green
}

Script 5: Post-Install Validation

Verify the app installed correctly:

<#
.SYNOPSIS
    Post-installation validation
#>
param(
    [Parameter(Mandatory=$true)]
    [string]$AppName,
    
    [Parameter(Mandatory=$false)]
    [string[]]$VerificationPaths
)

Write-Host "Validating $AppName installation..." -ForegroundColor Cyan

$ValidationPassed = $true

foreach ($Path in $VerificationPaths) {
    if (Test-Path $Path) {
        Write-Host "✓ Found: $Path" -ForegroundColor Green
    } else {
        Write-Host "✗ Missing: $Path" -ForegroundColor Red
        $ValidationPassed = $false
    }
}

# Check registry
$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\*"
$RegApps = Get-ItemProperty $RegPath -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -like "*$AppName*" }

if ($RegApps) {
    Write-Host "✓ Registry entry found" -ForegroundColor Green
} else {
    Write-Host "⚠ No registry entry (may be normal)" -ForegroundColor Yellow
}

if ($ValidationPassed) {
    Write-Host "`n✓ Validation PASSED" -ForegroundColor Green
    exit 0
} else {
    Write-Host "`n✗ Validation FAILED" -ForegroundColor Red
    exit 1
}

Wrap-Up

These scripts cover the full Win32 app lifecycle in Intune. Save them to your toolkit and customize for each app deployment.

Waitlist · planned for Dec 1, 2026

The Win32 Deployment Doctor

Read-only checks for Intune Win32 app deployments: a tenant audit of detection rules, return codes, dependencies and supersedence, plus an on-device IME log diagnostic. Join the waitlist and we'll email you when it ships. What it checks

We'll email you when it ships. Unsubscribe anytime. Privacy

#powershell #intune #win32 #app-deployment #automation