Forcing Win32App re-evaluation

I’ve been building Win32app packages for a couple of clients recently for deployment using Microsoft Endpoint Manager. Sometimes I would have problems with the builds when testing their deployment which meant fixing, repackaging and then redeploying the app. On occasion the nature of these problems would mean that the device wouldn’t attempt installation again. Windows thought the app was either successfully installed or it would wait 24hrs before trying the install again.

Whilst testing application deployments I would rather not have to wait when there is an error before trying again, so I began looking for solutions. There is a registry key that records the evaluated applications and their status, HKLM:\SOFTWARE\Microsoft\IntuneManagementExtension\Win32Apps

Deleting any sub-keys with a GUID name would force a re-evaluation of the software when the Intune Management Extension service was restarted or a sync performed. This is ok for one off problems but often I would be logged onto the device as a standard user and would have to elevate permissions to do this.

A solution I’ve come up with is to have an optional application in the Company Portal which when run will perform the required steps. This program runs a PowerShell script within the System context and so has permissions to delete the required registry keys, restart the service, start a sync before then creating a file to confirm completion.

To allow the application to be rerun/reinstalled a custom detection script would look for the file created by the script, delete it and then report success. This means that on the first run the detection script will report the application as installed successfully but when a reinstall is requested and the application is re-evaluated the file no longer exists and the app will be deployed once more.

These scripts are supplied without any warranty or support provided. I’m sure there are other ways to accomplish this so feel free to improve upon these but hopefully they provide an example of what could be done.

Main Script:

# Create log file location
$dest = "$($env:ProgramData)\Intune\scripts"
if (-not (Test-Path $dest)){mkdir $dest}

# Reset variables
$servicestarted = $false
$name = $null
$service = $null

# Remove existing installation marker
Remove-Item -Path "$($env:ProgramData)\Intune\scripts\reset-app-detection.ps1.tag" -Force

start-transcript "$dest\removeapps.log" -Append

write-host "loading Intune Win32App reg keys"

# Get Win32app reg key path(s)
$regkeys = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\IntuneManagementExtension\Win32Apps | Select-Object Name| where {$_.name -notlike "*\Reporting"}

# Loop through each path and remove it
foreach ($key in $regkeys)
{
$name = $key.name
$name = $name.replace("HKEY_LOCAL_MACHINE","HKLM:")
write-host "Remove Reg key $name"
Remove-Item -Path $name -Recurse
}

# Restart the Intune service
Restart-Service -Name IntuneManagementExtension

# Check and wait until service has restarted
while ($servicestarted -ne $true)
{
$service = Get-service IntuneManagementExtension
write-host "waiting for service to restart"
if ($service.status -eq 'Running'){$servicestarted = $true}
sleep -Seconds 1
}

# Confirm service has started
$service = Get-service IntuneManagementExtension
write-host "Service state is" $service.status

# Start scheduled task to force Intune synchronisation
write-host "Starting sync"
Get-ScheduledTask | ?{$_.TaskName -eq 'PushLaunch'} | Start-ScheduledTask

# Create file to confirm script has run
Set-Content -Path "$($env:ProgramData)\Intune\scripts\reset-app-detection.ps1.tag" -Value "Installed"
Stop-Transcript

Detection script:

$filecheck = "$($env:ProgramData)\Intune\scripts\reset-app-detection.ps1.tag"

if (test-path $filecheck)
{
Get-ChildItem $filecheck | where {($_.LastWriteTime -lt (get-date).AddSeconds(-60))} | Remove-Item -ErrorAction SilentlyContinue
write-host "Install complete"
}

About the author