Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reset-Appx.ps1 - Winget Company Portal install weird behavior, only showing for user after second run if $removeAppxPackage is null #5

Closed
Sn00zEZA opened this issue Jun 20, 2023 · 14 comments

Comments

@Sn00zEZA
Copy link

Sn00zEZA commented Jun 20, 2023

Picking up strange behavior when $removeAppxPackage is passed. Script will remove Company Portal using functions Remove-AppxPkg and Remove-AppxProvPkg, then successfully install Company Portal via winget, but its not detected by "Get-AppXPackage -AllUsers" in the Install-WinGetApp function. Running the script a second time it is detected successfully and the user will have Company Portal available.

Changing "$winGetTest = .\winget.exe list --id $winGetApp --source $winGetAppSource --accept-source-agreements" to include "--scope machine" shows that the app is indeed present. during both script runs.

Just not sure why it only works if $removeAppxPackage is null.

@byteben
Copy link
Owner

byteben commented Jun 20, 2023

Thanks for flagging as an issue, I saw this last night too. WinGet certainly does weird stuff as SYSTEM.

@Sn00zEZA
Copy link
Author

Sn00zEZA commented Jun 20, 2023

Made an update to the Install-WinGetApp function to rerun the winget install if it was not detected by "$testWinGetInstall = Get-AppXPackage -AllUsers | Where-Object { $_.Name -like $removeApp }". Not sure if this is best way, but it does work.

        if ($winGetAppInstallAttempted) {
            $testWinGetInstall = Get-AppXPackage -AllUsers | Where-Object { $_.Name -like $removeApp } -ErrorAction Stop
            
            #if (($testWinGetInstall.Name -eq $removeApp) -and ($testWinGetInstall.PackageUserInformation.UserSecurityId.Username -ne "NT AUTHORITY\SYSTEM")) {
            if (($testWinGetInstall.Name -eq $removeApp) -and ($testWinGetInstall.PackageUserInformation.UserSecurityId.Sid -ne "S-1-5-18")) {

                Write-Host "Success: The '$($winGetAppName)' app, with Id $($winGetApp), installed succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information"
                Write-LogEntry -logEntry "Success: The '$($winGetAppName)' app, with Id '$($winGetApp)', installed succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information" -logID $logID
            }
            else {
                Write-Warning -Message "Error: The '$($winGetAppName)' app, with Id '$($winGetApp)', did not install succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information"
                Write-LogEntry -logEntry "Error: The '$($winGetAppName)' app, with Id '$($winGetApp)', did not install succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information" -logID $logID -severity 3
                
                # Attempt to re-run installer if AppXPackage was not detected in the previous install
                Write-Host "Re-running install '$($winGetAppName)', with Id '$($winGetApp)', was not detected after previous attempt"
                Write-LogEntry -logEntry "Rerunning install '$($winGetAppName)', with Id '$($winGetApp)', was not detected after previous attempt" -logID $logID
                Write-Host ".\winget.exe install --id '$winGetApp' --accept-package-agreements --accept-source-agreements --source $winGetAppSource --scope machine"
                Write-LogEntry -logEntry ".\winget.exe install --Id '$winGetApp' --accept-package-agreements --accept-source-agreements --source $winGetAppSource --scope machine" -logID $logID
              
                .\winget.exe install --id $winGetApp --accept-package-agreements --accept-source-agreements --source $winGetAppSource --scope machine
                
                $testWinGetInstall = Get-AppXPackage -AllUsers | Where-Object { $_.Name -like $removeApp } -ErrorAction Stop
                if ($testWinGetInstall.Name -eq $removeApp) {

                    Write-Host "Success: The '$($winGetAppName)' app, with Id $($winGetApp), installed succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information"
                    Write-LogEntry -logEntry "Success: The '$($winGetAppName)' app, with Id '$($winGetApp)', installed succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information" -logID $logID
                }
                else {
                    Write-Warning -Message "Error: The '$($winGetAppName)' app, with Id '$($winGetApp)', did not install succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information"
                    Write-LogEntry -logEntry "Error: The '$($winGetAppName)' app, with Id '$($winGetApp)', did not install succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information" -logID $logID -severity 3
                }
            }
        }

@theITcloudAdmn
Copy link

theITcloudAdmn commented Jun 23, 2023

Thanks @Sn00zEZA
Had the same problem, your code modification solved it for me too.

Update:
As I'm further testing the modified script I've found out, that it only works if it runs twice. Not sure yet why...

@theITcloudAdmn
Copy link

Probably found out why @Sn00zEZA code update didn't solve the problem for me:
($testWinGetInstall.PackageUserInformation.UserSecurityId.Username -ne "NT AUTHORITY\SYSTEM")
I'm working on german Windows. In german OS it's "NT-AUTORITÄT\SYSTEM" (thanks Microsoft!)...

I think this is the better solution, the SID stays the same no matter the OS localization:
($testWinGetInstall.PackageUserInformation.UserSecurityId.Sid -ne "S-1-5-18")

@Sn00zEZA
Copy link
Author

Ah that would make sense. Will update my script with this also. Thank you for raising this.

@byteben
Copy link
Owner

byteben commented Jun 27, 2023

Thanks @theITcloudAdmn and @Sn00zEZA
This makes sense. I am also unsure why it needs running twice on some systems.

I will proceed with the code mod later today. Appreciate your input here!
Ben

@Guardempire
Copy link

I have tried the script in our environment and it works fine for those who have the old installation on the machine. If you set up a new device, which by default gets the new Company Portal via Winget, the script unfortunately uninstalls the portal directly again. If you run the script again, it is installed again, the next time then removed again. The change of Sn00zEZA does not solve the problem for me. Then, according to the log, it recognizes an existing version that it wants to update, finds no update, claims it was successful, but the portal is not present.

I run the script via Live Response Session, it should behave similar to Intune?

@byteben
Copy link
Owner

byteben commented Jun 27, 2023

Can you please try version 1.06.27.0
winget was installing the appxprovisionedpackage but the manifest was not registering which would result in the app not appearing for the logged on user. New users logging on should have the appx package provisioned ok

@Guardempire
Copy link

Guardempire commented Jun 28, 2023

Different behavior, same result. If it is started once and it is already present, it is not executable afterwards. If you start the script again, it works and then always in alternation. It is interesting that the script throws an error if it works afterwards. If there is no error at the end, the Company Portal does not work. I copy the message here, but unfortunately it is in German.

I start the script via the live response session on the notebook.

Errors:
Add-AppxPackage : Fehler bei Bereitstellung. HRESULT: 0x80073CF9, Fehler bei der Installation. Wenden Sie sich an den
Softwarehersteller. (Ausnahme von HRESULT: 0x80073CF9)
Der Bereitstellungsvorgang Register für das Paket "Microsoft.CompanyPortal_11.2.119.0_neutral_~8wekyb3d8bbwe" von der
Installationsanforderung "AppxBundleManifest.xml" wurde abgelehnt, da dieser Vorgang mit dem lokalen Systemkonto nicht
ausgeführt werden darf.
HINWEIS: Wenn Sie weitere Informationen wünschen, suchen Sie im Ereignisprotokoll nach [ActivityId]
b9c38e26-a8e1-0001-d9a6-cfb9e1a8d901, oder verwenden Sie die Befehlszeile Get-AppxLog -ActivityID
b9c38e26-a8e1-0001-d9a6-cfb9e1a8d901
In C:\ProgramData\Microsoft\Windows Defender Advanced Threat
Protection\Downloads\PSScript
{AC5BA350-DDF4-4F1B-B2DB-D1E33A23F074}.ps1:455 Zeichen:112

  • ... ch-Object { Add-AppxPackage -DisableDevelopmentMode -Register "$($_.I ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : WriteError: (C:\Program File...ppXManifest.xml:String) [Add-AppxPackage], IOException
    • FullyQualifiedErrorId : DeploymentError,Microsoft.Windows.Appx.PackageManager.Commands.AddAppxPackageCommand

@theITcloudAdmn
Copy link

theITcloudAdmn commented Jun 28, 2023

Would be super interesting to understand, why sometimes the app gets installed just for the system user in this strange state (check PackageUserInformation)!

So I ended up with this (not really nice but does the job):

  1. Adjusted the modification from @Sn00zEZA sligthly so if the app isn't installed correctly after 2nd try, script will end with exit code 1. Like that, Intune will do another rerun of the script which normaly ends with success. And I'm checking after both installation attempts if the app is there and not installed for System (SID "S-1-5-18").
        if ($winGetAppInstallAttempted) {
            $testWinGetInstall = Get-AppXPackage -AllUsers | Where-Object { $_.Name -like $removeApp } -ErrorAction Stop
        
            if (($testWinGetInstall.Name -eq $removeApp) -and ($testWinGetInstall.PackageUserInformation.UserSecurityId.Sid -ne "S-1-5-18")) {
        
                Write-Host "Success: The '$($winGetAppName)' app, with Id $($winGetApp), installed succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information"
                Write-LogEntry -logEntry "Success: The '$($winGetAppName)' app, with Id '$($winGetApp)', installed succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information" -logID $logID
            }
            else {
                Write-Warning -Message "Error: The '$($winGetAppName)' app, with Id '$($winGetApp)', did not install succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information"
                Write-LogEntry -logEntry "Error: The '$($winGetAppName)' app, with Id '$($winGetApp)', did not install succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information" -logID $logID -severity 3
                        
                # Attempt to re-run installer if AppXPackage was not detected in the previous install
                Write-Host "Re-running install '$($winGetAppName)', with Id '$($winGetApp)', was not detected after previous attempt"
                Write-LogEntry -logEntry "Rerunning install '$($winGetAppName)', with Id '$($winGetApp)', was not detected after previous attempt" -logID $logID
                Write-Host ".\winget.exe install --id '$winGetApp' --accept-package-agreements --accept-source-agreements --source $winGetAppSource --scope machine"
                Write-LogEntry -logEntry ".\winget.exe install --Id '$winGetApp' --accept-package-agreements --accept-source-agreements --source $winGetAppSource --scope machine" -logID $logID
                      
                .\winget.exe install --id $winGetApp --accept-package-agreements --accept-source-agreements --source $winGetAppSource --scope machine
                        
                $testWinGetInstall = Get-AppXPackage -AllUsers | Where-Object { $_.Name -like $removeApp } -ErrorAction Stop
                if (($testWinGetInstall.Name -eq $removeApp) -and ($testWinGetInstall.PackageUserInformation.UserSecurityId.Sid -ne "S-1-5-18")) {
        
                    Write-Host "Success: The '$($winGetAppName)' app, with Id $($winGetApp), installed succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information"
                    Write-LogEntry -logEntry "Success: The '$($winGetAppName)' app, with Id '$($winGetApp)', installed succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information" -logID $logID
                }
                else {
                    Write-Warning -Message "Error: The '$($winGetAppName)' app, with Id '$($winGetApp)', did not install succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information"
                    Write-LogEntry -logEntry "Error: The '$($winGetAppName)' app, with Id '$($winGetApp)', did not install succesfully. Check the Winget logs at 'C:\Windows\Temp\WinGet\defaultState' for more information" -logID $logID -severity 3
                    Write-Output -Message "Stopped processing the script with error code 1"
                    Write-LogEntry -logEntry "Stopped processing the script with error code 1" -logID $logID
                    Set-Location $PSScriptRoot
                    Exit 1
                }
            }
        }
  1. Built a remediation script as addition to detect if the app is correctly installed (as remediation the Reset-Appx.ps1 script is run):
$CheckApp = "Microsoft.CompanyPortal"

Try {
    $TestAppxInstall = Get-AppXPackage -AllUsers | Where-Object { $_.Name -like $CheckApp } -ErrorAction Stop
    If (($TestAppxInstall.Name -eq $CheckApp) -and ($TestAppxInstall.PackageUserInformation.UserSecurityId.Sid -ne "S-1-5-18")){
        Write-Output $TestAppxInstall
        Write-Output "Compliant - Found App '$($CheckApp)'"
        Exit 0
    } 
    Write-Output $TestAppxInstall
    Write-Warning "Not Compliant - App '$($CheckApp)' not found!"
    Exit 1
} 
Catch {
    Write-Output $TestAppxInstall
    Write-Warning "Not Compliant - Error processing Script!"
    Exit 1
}

Testing looks promising. Think I'm going to roll this out to production.

@byteben
Copy link
Owner

byteben commented Jun 28, 2023 via email

@byteben
Copy link
Owner

byteben commented Jun 29, 2023

Found the root cause of this. There are 2 possible error conditions after using winget to install the app as system. We can triage both now we understand the issue. Fix coming in v2 of script

@byteben
Copy link
Owner

byteben commented Jul 3, 2023

All 3 conditions listed below are fixed in V1.07.03.0 of Reset-Appx.ps1
Bug Fixes, Enhancements and Refactoring 🪲🌟🧑‍💻

Condition 1:
When WinGet installs the app as SYSTEM, the AppxPackage can fail to register so the AppxPackage regresses, resulting in the ap not being available for the user.

Condition 2:
The AppxPackage was staged as SYSTEM

Condition 3:
After the WinGet install, WinGet list did not detect the app

WinGet will retry 10 times (by default) to install the app successfully and ensure the conditions above are not present.
There is also a 30 second wait (by default) when testing the AppxPackage after WinGet has installed the app

@byteben byteben closed this as completed Jul 3, 2023
@ngjrjeff
Copy link

Sorry. I used the latest version of the script and i still have to run the second time before company portal app is visible to the user computer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants