• Welcome to Support Forum: Get Support for Patch My PC Products and Services.
 

PADT - RemoveMSIApplication

Started by samuel.olsson, April 26, 2024, 03:25:58 AM

Previous topic - Next topic

samuel.olsson

Hi,
I was wondering how these actions are performed when calling for RemoveMSIApplication in PADT.
Reason I ask, is that I'm trying to change the value returned as LastUsedSource to point it to a different location.
Thanks in advance!
Br
Samuel

Dan Gough (Patch My PC)

Hi,

Firstly, if this is an SCCM application, then SCCM has native functionality to manage the sourcelist; just browse to the MSI file via the bottom of the Programs tab of the Deployment Type properties. The Patch My PC Publisher does not fill this in, which is something I will raise.

If you want to add/replace the SourceList via PSADT though, there is a community extension for it here that you might find useful:

https://discourse.psappdeploytoolkit.com/t/msi-sourcelist-and-psadt/879

Otherwise, for a more manual approach using the registry, you can get the ProductCode of an MSI application via PSADT (which looks at the uninstall keys like HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall):

$ProductCode = (Get-InstalledApplication -Name 'Acrobat').ProductCode

Or native PowerShell:

$ProductCode = (Get-Package -Provider MSI | Where Name -match 'Acrobat').FastPackageReference

Then you will need to convert that GUID to a new format:

$CompressedGuid = -join (($ProductCode | Select-String -Pattern '^\{?(.{8})-(.{4})-(.{4})-(.{2})(.{2})-(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})\}?$' -AllMatches).Matches.Groups[1..11].Value | ForEach-Object { $CharArray = $_.ToCharArray(); [System.Array]::Reverse($CharArray); -join $CharArray })

Then you can look up the reg key "HKLM\SOFTWARE\Classes\Installer\Products\$CompressedGuid\SourceList".

Dan Gough (Patch My PC)

Furthermore; it looks like you were getting an error uninstalling an MSI because Windows Installer was looking for the cached MSI in order to perform the uninstall. So it wasn't a matter of where the PSADT Remove-MsiApplications function was looking for the MSI, it's more that Windows Installer itself was looking for it. When this happens, you can update the sourcelist for the app as above.

samuel.olsson

Hi Dan,
Thanks for trying to help!
I tried your fix. Unfortunately it's still looking for the msi file in the old location even after changing the path in that reg key.
I've searched through the registry for other places where that SourceList might be found and changing the path ther as well. Still no luck.

Dan Gough (Patch My PC)

There is a HKCU equivalent of that key also in case it was a per-user MSI:

HKEY_CURRENT_USER\Software\Microsoft\Installer\Products

Windows Installer also caches MSIs under C:\Windows\Installer with a random filename, check out the LocalPackage value under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\$CompressedGuid\InstallProperties.

If all else fails and you need to take the nuclear option to remove the record of an MSI from the system (which may leave some of its contents behind), there is MsiZap.exe from Microsoft; and there is a community PSADT extension for it here:

https://discourse.psappdeploytoolkit.com/t/psadt-msizap-extension/4431

Although I should point out this extension replaces an existing toolkit function Execute-Msi, which is not good practice.

JustAnotherUser

I love PSADT and we have it doing lots of fun tricks. That said, rather than sourcing a big workaround here, do it natively or use a different psadt function. I'm typing on a phone so please forgive bad syntax.

To wit:

I'd put the old msi in the SupportFiles folder.

Then, I would make a pre-install step that checked for the existence of the old app, whether by wmi query or just a test path or file version or date or reg path or whatever feels best.

Then either:
Execute-Msi -action "uninstall" -path "$dirSupportFiles/msiname.Msi"

Or just do it with native powershell, something like
Start-process "msiexec.exe" ArgumentList "/x $dirSupportFiles/msiname.exe /qn /l*V c:\logpath\log.log"

Either way reference the old msi in the package contents. Wee bit sloppy but then you don't need to use supersedence or guid's  or worry about cached msi availability or distribution point content of retired apps or any of that mess. 



Dan Gough (Patch My PC)

I have done some further testing around this - if the original source MSI (where it was installed from) and the cached MSI (from C:\Windows\Installer) are no longer available, then trying to uninstall it with just the filename will not work and you'll get a 1612 error.

I have just found a much simpler way, which is to add REINSTALLMODE=v to the command line when uninstalling. Any of these will recache the MSI:

msiexec /i app.msi /qn REINSTALLMODE=v
msiexec /fv app.msi /qn

Or you can also add it to the uninstall:

msiexec /x app.msi /qn REINSTALLMODE=v


If you are using PSADT, then you can run:

Execute-MSI -Action Install -Path 'app.msi' -SkipMSIAlreadyInstalledCheck -AddParameters 'REINSTALLMODE=v'
Execute-MSI -Action Repair -Path 'app.msi' -RepairFromSource $true
Execute-MSI -Action Uninstall -Path 'app.msi' -AddParameters 'REINSTALLMODE=v'


samuel.olsson

Quote from: Dan Gough on May 08, 2024, 02:28:52 AMI have done some further testing around this - if the original source MSI (where it was installed from) and the cached MSI (from C:\Windows\Installer) are no longer available, then trying to uninstall it with just the filename will not work and you'll get a 1612 error.

Yeah, I stumbled upon the exact same issue today, but solved it by reinstalling from a new source and then uninstalling.

Quote from: Dan Gough on May 08, 2024, 02:28:52 AMI have just found a much simpler way, which is to add REINSTALLMODE=v to the command line when uninstalling. Any of these will recache the MSI:

msiexec /i app.msi /qn REINSTALLMODE=v
msiexec /fv app.msi /qn

Or you can also add it to the uninstall:

msiexec /x app.msi /qn REINSTALLMODE=v


If you are using PSADT, then you can run:

Execute-MSI -Action Install -Path 'app.msi' -SkipMSIAlreadyInstalledCheck -AddParameters 'REINSTALLMODE=v'
Execute-MSI -Action Repair -Path 'app.msi' -RepairFromSource $true
Execute-MSI -Action Uninstall -Path 'app.msi' -AddParameters 'REINSTALLMODE=v'
I will most definitely try this. Thank you!

samuel.olsson

Quote from: Dan Gough on May 08, 2024, 02:28:52 AMI have done some further testing around this - if the original source MSI (where it was installed from) and the cached MSI (from C:\Windows\Installer) are no longer available, then trying to uninstall it with just the filename will not work and you'll get a 1612 error.

I have just found a much simpler way, which is to add REINSTALLMODE=v to the command line when uninstalling. Any of these will recache the MSI:

msiexec /i app.msi /qn REINSTALLMODE=v
msiexec /fv app.msi /qn

Or you can also add it to the uninstall:

msiexec /x app.msi /qn REINSTALLMODE=v


If you are using PSADT, then you can run:

Execute-MSI -Action Install -Path 'app.msi' -SkipMSIAlreadyInstalledCheck -AddParameters 'REINSTALLMODE=v'
Execute-MSI -Action Repair -Path 'app.msi' -RepairFromSource $true
Execute-MSI -Action Uninstall -Path 'app.msi' -AddParameters 'REINSTALLMODE=v'
This worked brilliantly! Thanks a lot for your efforts, Dan!