Reputation: 323
I'm trying to create a very simple script which would check if the a specific program is installed and if so return the version number for that program.
I've been able to get to the point where I'm running the script and able to return a binary value if a program is installed or not but not sure how to return the version number for that installed program.
What I will post will be just what I'm doing to return if program is installed, and need help in then attaining the version number.
function Check_Program_Installed {
$my_check = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, InstallDate |
Format-Table -AutoSize |
Out-String
# Check if Google Chrome is installed
$my_check -Match "Google Chrome"
}
Check_Program_Installed
Upvotes: 3
Views: 12992
Reputation: 440471
tl;dr
In Windows PowerShell[1] v5.1+, use the following (searches among both 32-bit and 64-bit installed programs, as shown in Control Panel):
Get-Package -ProviderName Programs -IncludeWindowsInstaller '*Google Chrome*' |
ForEach-Object Version
Note: The 32-bit-only HKEY_LOCAL_MACHINE:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
registry key may have more specific entries than what Control Panel shows - I'm unclear on why, but perhaps the composite view in Control Panel is sufficient.
Applied to your example:
PS> (Get-Package -ProviderName Programs -IncludeWindowsInstaller '*Google Chrome*').Version
70.0.3538.67
As for what you tried:
Since you're checking the Wow6432Node
registry key branch specifically, you're checking installed 32-bit programs only.
As such, a better name for your function would be Check_32BitProgram_Installed
or, more in line with with the function's intent, using an approved PowerShell verb, Get-32BitProgramVersion
.
Alternatively, name, the function Get-ProgramVersion
and look in both the 32-bit and 64-bit locations and process the results as shown in Theo's and Kevin M. Lapio's and Shawn Esterman's helpful answers:
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*,
HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
In line with the generic title of your question, the above is a solution that essentially searches the list of installed applications you would see in Control Panel > Programs > Programs and Features (appwiz.cpl
), which covers both 32-bit and 64-bit applications:
Windows PowerShell v5.1 comes with the PackageManagement
module and a Programs
package provider[1] that allows inspecting installed programs via the Get-Package
cmdlet; in PSv3 and PSv4, it is possible to manually install it.
To list installed programs (shown with abridged sample output):
PS> Get-Package -ProviderName Programs -IncludeWindowsInstaller
Name Version Source ProviderName
---- ------- ------ ------------
Git version 2.18.0 2.18.0 Programs
Microsoft Azure Compute Emu... 2.9.8699.20 Programs
Microsoft Azure Authoring T... 2.9.8699.20 Programs
# ...
The output objects are of type [Microsoft.PackageManagement.Packaging.SoftwareIdentity]
, which have .Name
and .Version
properties, which enables the solutions above.
The Programs
package provider supports two dynamic options (options specific to that provider):
-IncludeWindowsInstaller
is needed to make the list of programs reported match what Control Panel shows.
-IncludeSystemComponent
, by contrast, reports components that do not show in Control Panel.
[1] Unfortunately, the underlying Programs
package provider is not available in PowerShell Core on Windows as of v7.0 - and I'm unclear on whether that is a not-yet situation or whether it will never be - see GitHub issue #13225.
Upvotes: 2
Reputation: 388
Instead of doing the match after formatting the table, you could add a where to select the result you need beforehand and then obtain the DisplayVersion
directly from that object. You could clean this up more to do exactly what you need, but here is your code modified to retrieve and display the number if the application is found. Try switching to a bad name to see the else
result:
function Get-ApplicationVersion {
$applicationName = "Google Chrome"
$my_check = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, InstallDate | Where -Property DisplayName -Match $applicationName
$versionNumber = $my_check.DisplayVersion
if ($my_check) {
$versionNumber
}
else {
write-warning "Application not found"
}
}
Get-ApplicationVersion
EDITED: Renamed function name from Check_Program_Installed
to use PS common verb Get
, per suggestion.
Upvotes: 5
Reputation: 2342
function Get-InstalledProgram {
Param (
$ProgramName
)
$UninstallKeys = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
if ( $ProgramName )
{
$UninstallKeys | Where-Object -Property DisplayName -Match -Value $ProgramName | Select-Object DisplayName, DisplayVersion, InstallDate
}
else
{
$UninstallKeys | Select-Object DisplayName, DisplayVersion, InstallDate
}
}
If you wanted to see all the programs, then you don't have to add a parameter. Just pipe its output to Format-Table
. Format-Table does some weird just where the items are no longer the objects you're expecting, but table objects. Here is how I would handle that:
Get-InstalledProgram | Format-Table -Autosize
If you want to search for a program, add a parameter. You'll see above I added a parameter for ProgramName. It will match this term to the registry key's DisplayName.
PS C:\> Get-InstalledProgram -ProgramName Java
DisplayName DisplayVersion InstallDate
----------- -------------- -----------
Java 8 Update 181 8.0.1810.25 20180725
Java Auto Updater 2.8.181.13 20180925
If you wanted to just get the version, I would recommend just piping your output to Select-Object -ExpandProperty DisplayVersion
PS C:\> Get-InstalledProgram -ProgramName 'Java 8' | Select-Object -ExpandProperty DisplayVersion
8.0.1810.25
Upvotes: 4
Reputation: 61253
If you want that function to look for a specific installed program instead of returning a (table) formatted string, then you could simply do:
function Check_Program_Installed {
[CmdletBinding()]
Param(
[Parameter(Position = 0, Mandatory=$true, ValueFromPipeline = $true)]
$Name
)
$app = Get-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" |
Where-Object { $_.DisplayName -match $Name } |
Select-Object DisplayName, DisplayVersion, InstallDate, Version
if ($app) {
return $app.DisplayVersion
}
}
Check_Program_Installed "Google Chrome"
This will return $null
when not found, or the version as string like 70.0.3538.67
Upvotes: 5