How to check if a program is installed and install it if it is not?
41,854
$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
}
Author by
Joshua Fletcher
Updated on February 23, 2020Comments
-
Joshua Fletcher about 4 years
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), theGet-ItemProperty
is returning a result that should be counting as something other than$null
. -
Jez over 8 yearsYou're welcome. Can you then please mark it as the answer?(it's the tick under the down arrow).
-
Bajan over 6 yearsI found this very useful, would you mind explaining what the code: If ([IntPtr]::Size -eq 4) is checking for? Thank you!
-
Chris Vermeijlen over 6 yearsHi, I also have a question. Mind explaining the'' $msiArgs -Wait -Passthru'' part please? Thanks!
-
Jez over 6 years@Bajan it's a method to determine the OS architecture. The value of the [IntPtr] property is 4 in a 32-bit process, and 8 in a 64-bit process.
-
Jez over 6 years@ChrisVermeijlen; $msiArgs is just a variable to store the arguments you want to pass onto the MSI, in the example above we are just passing "-qb". You could store any other MSI argument like, "/norestart ALLUSERS=2" etc. The "-wait -Passthru" are parameters for the Start-Process cmdlet: docs.microsoft.com/en-us/powershell/module/…
-
Tom Padilla over 6 yearsOne question: why the -Passthru on the Start-Process when there's nothing to passthru to? If you are not piping the result to anything what is -Passthru for?
-
Jez over 6 years@Tom Padilla - Yes, if the script is on its own, you don't need it, but the OP had it in their original code to pipe out the ExitCode.