Sometimes instead uninstalling MSI, a simple repair would be the best. When distributing your application the sources will become unavailable once the local cache will become empty. So the repair will not work. A solution would be to make the MSI available somewhere. But how making the MSI “knowing” the sources are available somewhere?
- In the registry, go to HKCR\installer\Products<product code of the product>\sourcelist\net
You will notice where the Windows Installer will look to find the msi location. If the path is no longer existing then the repair will not work.
Function AddSourceList {
<#
.SYNOPSIS
Ajoute un chemin au sourcelist d'un MSI
.DESCRIPTION
Ajoute un chemin au sourcelist d'un MSI
.Parameter
Str_MSIPathAndFile
Donner un chemin complet d'un MSI incluant le nom du fichier. Le
MSI doit se trouver dans le répertoire.
.EXAMPLE
AddSourcelist MSI
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$Str_MSIPathAndFile
)
Begin {
## Get the name of this function and write header
[string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -CmdletBoundParameters $PSBoundParameters -Header
}
Process {
Try {
$MSIPath=split-path $Str_MSIPathAndFile
$ProductCode= Get-MsiTableProperty -Path $Str_MSIPathAndFile
#$productcode='{09AAAB09-6DBA-4DD9-9865-54597D3FBCA8}'
#$MSIPath='E:\Temp\Logiciels\Antidote 8\msi\druide'
$Com_WI = New-Object -ComObject WindowsInstaller.Installer
$codeInvokeMethod = {
$type = $this.gettype();
$index = $args.count - 1;
$methodargs = $args[1..$index]
$type.invokeMember($args[0], [System.Reflection.BindingFlags]::InvokeMethod, $null, $this, $methodargs)
}
$Com_WI = $Com_WI | Add-Member -MemberType ScriptMethod -Value $codeInvokeMethod -Name InvokeMethod -PassThru
Try {
Write-log 'Ajout du Sourcelist $($MSIPath) au MSI $($Str_MSIPathAndFile) Product code $($productcode.productcode)'
$Com_WI.InvokeMethod('AddSource', '$($productcode.productcode)', '', '$($MSIPath)')
}
Catch {
Write-Log -Message "Failed to resolve registry path [$regKey]. `n$(Resolve-Error)" -Severity 3 -Source ${CmdletName}
Continue
}
}
catch {
Write-Log -Message "Failed to resolve registry path [$regKey]. `n$(Resolve-Error)" -Severity 3 -Source ${CmdletName}
Continue
}
}
End {
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer
}
}
After running that function, you will see a second path appeared in the Net section in the registry.
I would suggest PSADTK to include something like that in the toolkit
Thanks,