Call4Cloud | MMP-C | Autopilot | Device Preparation

Retry Win32 App Lola Retry

Patch My Pc | install & update thousands of apps

When a Win32app fails to install, figuring out the root cause can be frustrating. We often need to trigger the installation repeatedly to get to the bottom. In this blog, we’ll look at the different ways to retry a failed app installation. Whether it’s waiting for the GRS to kick in, using the Company Portal, digging into the registry, or using a PowerShell tool to retry a failed win32app, I’ll walk you through the options to help you get the app reinstalled and working properly.

1. Retry Failed Win32app Installation

Of course, we need to repeatedly trigger the installation to determine the root cause when a Win32 app fails to install. So, what options do we have when we want to retry the failed app and reinstall it? After the three times for five minutes, it will wait 24 hours before the GRS / “Global re-evaluation schedule” kicks in. It isn’t very good.

The Global Re-evaluation Schedule (GRS) in Intune is a mechanism that determines when a failed Win32 app installation should be retried. When an app installation fails, the Intune Management Extension (IME) sets a re-evaluation time, typically based on a 24-hour interval. During this period, the IME logs track the app’s status and check whether the conditions for a retry are met. Every hour, the IME syncs and checks the GRS to see if the re-evaluation interval has expired.

If the app’s installation has not been retried within the set interval (usually 24 hours), the GRS will trigger a new installation attempt. If the failure is due to an exit code specified for retry, the system will attempt to reinstall the app three times, with 5-minute intervals between each attempt, before reverting to the 24-hour schedule. If the exit code is not managed or is set to “Failed,” the GRS will only trigger a retry once every 24 hours. The GRS ensures that retries are spaced out to avoid constant reinstallation attempts, which helps in managing network and device resources effectively.

So, how are we going to deal with the GRS?

1.1. Waiting

We could wait 24 hours for it to retry, and hopefully, the GRS will kick in to try to reinstall the Win32 app someday.

the Win32 app failed to be installed and the GRS will now retry to install the app the next day. Retry Failed win32app

I guess that’s not the best option we got! But if you don’t care about waiting… this option is the easiest one!

1.2. Company Portal

Of course, everyone uses the Wonderfull Company App and everyone has also assigned the Apps as available so end users can install the apps or reinstall the apps on their own?. When the apps are also made available, we could trigger a reinstallation from the Company App?

Even when your device is “shared” you could initialize a reinstall?

Please note: When triggering the reinstall, the detection phase will first be launched, and you can guess what happens when it detects the program! The reinstallation will be skipped!

When you don’t want to wait until the company portal app gives you the possibility to reinstall the app as shown above (sorry for the Dutch words) there is still another method available to speed things up!

1.3. The Registry

The best way you could trigger the immediate reinstallation of a Win32App that failed to install is by opening the registry and browsing the IntuneManagementExtension key

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\IntuneManagementExtension\Win32Apps\{SID}\{App Id GUID}

First, you will need to find the Win32 App you are after. But to do so, you will need the have the right App ID. Again you have multiple options to find the needed GUID!

  • You could start looking in the Intune Management Extension event log. As we noticed earlier, it will mention the download and the corresponding App ID
  • The second way to find this GUID is to open the Endpoint Manager and click on the App that needs to be reinstalled. When you select the App, you can make a copy of the GUID in the URL after /appId/.

When we have the app ID, we are good to go. Just search for it and open the corresponding registry key. When you are sure the app is failing (for example, exit code 1603), you need to remove the whole subkey “159aeebd-fe8a-4571-98ef-de8c72ff5ed5”, just like I have marked with a nice red square, and restart the Intune Management Extension.

win32app exit code

If you want to know more about how these exit codes work and how detection rules work please read this blog as it should tell you more about it

https://call4cloud.nl/2022/08/the-ballad-of-buster-exitcodes

If you don’t want to wait, just delete the whole AppId key it’s also enough to modify the “DownloadStartTimeUTC” in the past 24 hours and wait for the installation will be retried by the GRS schedule.

Please read part 1.4, as it mentions an important update in the WIn32app Install retry flow!

1.4 GRS Manager

It looks like deleting only that key isn’t enough after the Intune Management Extension service was updated some time ago. After you delete the reg key, as shown above, we need to look at the IME log using the CMtrace tool. Inside the IME log, GRSManager will tell you that the App with a specific hash has not expired.

the grsmanager showing that the appid is not expired: grstimeutc

We will also notice that the ReevaluationScheduleManager mentions the same hash we noticed earlier! So please make sure after deleting the first GUID, you also delete that specific GRS key!

the win32app GRS key

So, how are we going to find the right GRS key?

2. A PowerShell Tool

Finding the registry key manually with the cmtrace tool could take some time, and we all know time is valuable, so why not use a Powershell script to do so? Before we can start, we need to find the corresponding App ID from the AppId we want to retry. You can find the AppId by opening the app in the Intune Portal and copy-pasting the app ID in the script below

So in the example above, it is d8981105-3d0e-4cf2-9d7f-6ab00c2573d2. I will use that one and query the appworkload.log for the correct hash.


$appId = "d8981105-3d0e-4cf2-9d7f-6ab00c2573d2"

$intuneLogList = Get-ChildItem -Path "$env:ProgramData\Microsoft\IntuneManagementExtension\Logs" -Filter "appworkload*.log" -File | sort LastWriteTime -Descending | select -ExpandProperty FullName

if (!$intuneLogList) {
Write-Error "Unable to find any Intune log files. Redeploy will probably not work as expected."
return
}

foreach ($intuneLog in $intuneLogList) {
$appMatch = Select-String -Path $intuneLog -Pattern "\[Win32App\]\[GRSManager\] App with id: $appId is not expired." -Context 0, 1
if ($appMatch) {
foreach ($match in $appMatch) {
$Hash = “”
$LineNumber = 0
$LineNumber = $match.LineNumber
$Hash = Get-Content $intuneLog | Select-Object -Skip $LineNumber -First 1
if ($hash) {
$hash = $hash.Replace('+','\+')
return $hash
}
}
}
}

With that hash we now know which key we need to delete instead of just deleting them all.

3. PowerShell Remediation Scripts

Besides using a PowerShell script manually for each, we could also use PowerShell remediations to automatically fix it each day or each hour!

Remediation Script Summary:

  • Starts Logging:
    The script begins by starting a log file in the C:\ProgramData\Microsoft\IntuneManagementExtension\Logs directory, timestamped for tracking.
  • Identifies Failed Win32 App Installations:
    It retrieves the list of failed Win32 app states from the registry under HKLM:\SOFTWARE\Microsoft\IntuneManagementExtension\Win32Apps. Each failure is identified based on specific error codes.
  • Maps User and App Information:
    For each failure, the script parses registry paths to extract user and app IDs. It then retrieves the associated username and an error description for clarity.
  • Cleans Up Registry Keys:
    The script removes relevant registry entries for each failed app installation, including general and GRS-specific keys, to trigger reinstallation attempts by Intune.
  • Restarts Intune Management Extension:
    If any failures were detected, the script restarts the Intune Management Extension service to apply changes and retry installations.
  • Stops Logging:
    After processing, the script stops the logging session to complete the remediation.

With the remediation explained, please download the files below

After downloading the PowerShell scripts you need to upload them to Intune.

When assigning the Remediation to your user group, don’t forget to change the schedule to make sure the remediation is executed each day or each hour!

Another option if you don’t want to schedule it is to execute the remediation on demand!

Conclusion

It’s great to be able to retry failed apps! Hopefully, you also read part 1.4, which mentions the GRS manager key. Sometimes, Microsoft updates the IME, and with it, some things change!

Updates GIFs - Get the best GIF on GIPHY

12 thoughts on “Retry Win32 App Lola Retry

  1. Hi Rudy, thanks for the explanation.
    Deleting the entire IntuneManagementExtension key and restarting the service has been my style for years now. However, if i install an app through the Company Portal, and uninstall it (manually don’t know if this makes a difference), the app status in the cloud portal is not updated. Still on ‘installed’. It takes forever, sometimes half a day to update, and is preventing reinstallation. Do you know how the application status for all apps can be rechecked / updated?

    1. I have the same issue with the install status in intune, which is not refreshing – not reliable the information, which intune is providing.

  2. Thanks, for the article. Deleting all findings with APP-ID and restarting the management extension service resolves this issue for me as well.

  3. 1.3 Mentions “Just search for it and”…

    Search for it where? The Find feature of the regedit rarely works, it seems.

  4. Even going nuclear on the regedit isn’t working here. For some reason I couldn’t find the appid reflected in the registry either so I deleted them all. I also deleted all GSR entries, restarted the machine, etc – the company portal’s app is still “Installing….”

    “Luckily” I am going home so it will be fixed on monday, but it’s extremely frustrating when it gets stuck

  5. Hello,

    The script was not working for me too. MAybe logs have changed.
    So I try to modify it. It seems work on my problem that I had.

    Thanks for your blog post Rudy by the way. 😉 Very usefull.

    Just for explain our case. We have an app (SAP) that need Excel to install. But we have several differents win 32 apps for Office (Office 365, Office 2021, with access, without access…) so we can’t use dependencies. And sometimes SAP try ton install before Office so we need to wait 24h for SAP to install…

    I am not a Powershell export, that’s why there is no more REGEX… So be conciliatory please. 😉

    Just replace the appid by your app id :
    $appId = “a1d259fe-685d-4f75-bd6b-2785f9bb3688”

    $intuneLogList = Get-ChildItem -Path “$env:ProgramData\Microsoft\IntuneManagementExtension\Logs” -Filter “IntuneManagementExtension*.log” -File | sort LastWriteTime -Descending | select -ExpandProperty FullName

    if (!$intuneLogList) {
    Write-Error “Unable to find any Intune log files. Redeploy will probably not work as expected.”
    return
    }

    foreach ($intuneLog in $intuneLogList) {
    $appMatch = Select-String -Path $intuneLog -Pattern “\[Win32App\]\[GRSManager\] App with id: $appId is not expired.” -Context 0, 1
    if ($appMatch) {
    foreach ($match in $appMatch) {
    $Hash = “”
    $LineNumber = 0
    $LineNumber = $match.LineNumber
    $Hash = Get-Content $intuneLog | Select-Object -Skip $LineNumber -First 1
    if ($hash) {
    Write-Host $Hash
    }
    }
    }
    }

  6. The ‘+’ symbol in the returned has would break the regex search, i added the following to make it work for me.

    if ($hash) {
    $hash = $hash.Replace(‘+’,’\+’)
    return $hash
    }

  7. Another updated script (25jan2023)
    param(
    [String]$AppId = ”
    )

    if ([string]::IsNullOrEmpty($AppId)) {
    Write-Host “Parameter -AppId should have a value, it is empty or null”
    return 1
    }

    function _getAppGRSHash {
    param (
    [Parameter(Mandatory = $true)]
    [string] $appId
    )

    $intuneLogList = Get-ChildItem -Path “$env:ProgramData\Microsoft\IntuneManagementExtension\Logs” -Filter “IntuneManagementExtension*.log” -File | Sort-Object LastWriteTime -Descending | Select-Object -ExpandProperty FullName

    if (!$intuneLogList) {
    Write-Error “Unable to find any Intune log files. Redeploy will probably not work as expected.”
    return
    }

    foreach ($intuneLog in $intuneLogList) {
    $patt = “\[Win32App\]\[GRSManager\] Found GRS value:.+\\GRS\\(.+)\\$appId\.\]”
    $appMatch = Select-String -Path $intuneLog -Pattern $patt

    if ($appMatch) {
    foreach ($match in $appMatch) {
    Write-Host “Log Entry: $match”
    $hash = ([regex]”$patt”).Matches($match).captures.groups[1].value
    if ($hash) {
    return $hash
    }
    }
    }
    }

    Write-Error “Unable to find App ‘$appId’ GRS hash in any of the Intune log files. Redeploy will probably not work as expected”
    }

    [String]$grsHash = _getAppGRSHash -appId $AppId
    Write-Host “App ID: $AppId”
    Write-Host “GRS Key: $grsHash”

  8. Will the same steps apply to UWP based apps or will these steps only work for win32 deployments from intune?

  9. PSCustomObject doesn’t seem to offer a `count` property.
    `$failedStates.Count` in your detection script keeps returning ‘0’ objects.
    using `$failedStates.PSobject.Properties.Value.count` works better.

    source:
    https://stackoverflow.com/questions/55064810/get-psobject-array-size-or-count

Leave a Reply

Your email address will not be published. Required fields are marked *

22  −    =  14

Proudly powered by WordPress | Theme: Wanderz Blog by Crimson Themes.