Free tool · Runs in your browser
Intune Win32 Detection & Requirement Script Builder
Build a PowerShell detection or requirement script for an Intune Win32 app, or a Configuration Manager script detection method, without starting from a blank file. Pick a file version, registry value, MSI product code or Windows service check and the script updates as you type. Every script writes to STDOUT and exits 0 only when the app is found, exits 1 silently when it is not, and catches errors so a typo in a path never writes to STDERR.
Nothing you type leaves the browser. Test the script on a pilot device before you assign the app beyond a test group.
<#
.SYNOPSIS
Intune Win32 detection script for Vendor App.
Detected when C:\Program Files\Vendor\App\app.exe ProductVersion >= 1.4.2.0.
.DESCRIPTION
Detected : one line on STDOUT, exit 0
Not detected : no STDOUT, exit 1
Any error : no STDOUT or STDERR, exit 1 (reported as not detected)
.NOTES
Intune: Detection rules > Use a custom detection script.
Run script as 32-bit process on 64-bit clients: No. Enforce script signature check: No
unless the script is signed. Save as UTF-8 with BOM.
Generated by the AdminSignal Intune Win32 Detection Script Builder:
https://www.adminsignal.com/tools/intune-win32-detection-generator
#>
$ErrorActionPreference = 'Stop'
function ConvertTo-ComparableVersion {
# Pads to four parts so 1.4 compares equal to 1.4.0.0, and keeps only the leading
# dotted number so values such as '1.4.2.0 (x64)' or '1, 4, 2, 0' still compare.
param([AllowNull()][object]$Value)
if ($null -eq $Value) { return $null }
$text = ([string]$Value).Trim() -replace '\s*,\s*', '.'
$match = [regex]::Match($text, '\d+(\.\d+){0,3}')
if (-not $match.Success) { return $null }
$parts = @($match.Value.Split('.') | ForEach-Object { [int]$_ })
while ($parts.Count -lt 4) { $parts += 0 }
return [version]::new($parts[0], $parts[1], $parts[2], $parts[3])
}
try {
$detected = $false
$evidence = ''
$required = ConvertTo-ComparableVersion '1.4.2.0'
$path = [Environment]::ExpandEnvironmentVariables('C:\Program Files\Vendor\App\app.exe')
if (Test-Path -LiteralPath $path -PathType Leaf) {
# ProductVersionRaw is built from the numeric version resource, not the display string
$installed = ConvertTo-ComparableVersion (Get-Item -LiteralPath $path).VersionInfo.ProductVersionRaw
if ($null -ne $installed -and $installed -ge $required) {
$detected = $true
$evidence = "$path ProductVersion $installed"
}
}
if ($detected) {
Write-Output $evidence
exit 0
}
# Not detected: no output, non-zero exit
exit 1
}
catch {
# Write nothing: any STDERR output makes Intune report the app as not installed
exit 1
}What IntuneManagementExtension.log expects
| Exit code | STDOUT | Result |
|---|---|---|
| Exit 0 | Text on STDOUT | Detected (installed) |
| Exit 0 | Empty STDOUT | Not detected |
| Exit ≠ 0 | Anything | Not detected (script failed) |
| Exit 0 | Any STDERR text | Not detected, even with STDOUT |
Current IME builds log Win32 detection and requirement results to AppWorkload.log in C:\ProgramData\Microsoft\IntuneManagementExtension\Logs; older builds write them to IntuneManagementExtension.log. ConfigMgr script detection uses the same STDOUT rule but reports a non-zero exit as Unknown.
Add the script to a Win32 app
- Pick the detection type and operator, then replace the example path, key, product code or version with the values from a device where the app is installed.
- Copy or download the script. The download is saved as UTF-8 with BOM, which Intune recommends for uploaded scripts.
- In the Intune admin center, open the Win32 app, go to Detection rules, choose "Use a custom detection script" and upload the file. For a requirement script, add it under Requirements > Script with output data type Boolean, operator Equals, value Yes.
- Leave "Run script as 32-bit process on 64-bit clients" at No unless you have a reason to change it. Registry reads in these scripts open an explicit registry view, so the result does not change either way.
- Prove the rule on a pilot device three times: not detected before install, detected after install, not detected after uninstall. Run the script as SYSTEM (for example with PsExec -s) to see what Intune sees.
32-bit, 64-bit and Sysnative
Most “installed but not detected” tickets come from looking in the wrong half of the registry. The Intune Management Extension launches install commands as a 32-bit process, so a reg.exe or powershell.exe call in the install command writes to HKLM\SOFTWARE\WOW6432Node unless it is called through %SystemRoot%\Sysnative\. A 32-bit MSI does the same by design.
The generated scripts open the registry with RegistryKey.OpenBaseKey and an explicit RegistryView, so the 32-bit toggle decides which view is read, not the bitness of the process Intune happens to start. MSI checks look in both Uninstall keys and never query Win32_Product, which runs a consistency check against every installed MSI.
Version checks pad each side to four parts before comparing, so a vendor that writes 1.4 to the registry still matches a required 1.4.0.0, and a [version] comparison never sorts 1.10 below 1.9 the way a string comparison does.
When detection still fails
- Separate ConfigMgr content failures from detection failures before you repackage for IntuneTell a content failure from a detection failure before you rebuild the same app for Intune.
- Intune Win32 App Install Stuck at Waiting, Pending, Installing, or FailedFind what is holding a Win32 app at "waiting for install status" and clear it safely.
- Intune Remediation Script Not Running, Detecting, Remediating, or ReportingProve whether a Remediation ran, failed or just has not reported yet, then fix the right thing.