How to check if a program is installed and install it if it is not?

Joshua Fletcher picture Joshua Fletcher · Jul 30, 2015 · Viewed 35.6k times · Source

I would rather not use WMI due the integrity check.

This is what I have that does not work:

$tempdir = Get-Location
$tempdir = $tempdir.tostring()

$reg32 = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
$reg64 = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"

if((Get-ItemProperty $reg32 | Select-Object DisplayName | Where-Object { $_.DisplayName -Like '*Microsoft Interop Forms*' } -eq $null) -Or (Get-ItemProperty $reg64 | Select-Object DisplayName | Where-Object { $_.DisplayName -Like '*Microsoft Interop Forms*' } -eq $null))
        {
        (Start-Process -FilePath $tempdir"\microsoft.interopformsredist.msi" -ArgumentList "-qb" -Wait -Passthru).ExitCode
        }

It always returns false. If I switch it to -ne $null it always returns true so I know it is detecting $null output even though, I believe (but could be wrong), the Get-ItemProperty is returning a result that should be counting as something other than $null.

Answer

Jez picture Jez · Jul 30, 2015
$tempdir = Get-Location
$tempdir = $tempdir.tostring()
$appToMatch = '*Microsoft Interop Forms*'
$msiFile = $tempdir+"\microsoft.interopformsredist.msi"
$msiArgs = "-qb"

function Get-InstalledApps
{
    if ([IntPtr]::Size -eq 4) {
        $regpath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
    }
    else {
        $regpath = @(
            'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
            'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
        )
    }
    Get-ItemProperty $regpath | .{process{if($_.DisplayName -and $_.UninstallString) { $_ } }} | Select DisplayName, Publisher, InstallDate, DisplayVersion, UninstallString |Sort DisplayName
}

$result = Get-InstalledApps | where {$_.DisplayName -like $appToMatch}

If ($result -eq $null) {
    (Start-Process -FilePath $msiFile -ArgumentList $msiArgs -Wait -Passthru).ExitCode
}