检查是否安装了特定版本的程序

Check if program with specific version is installed

我正在尝试创建一个非常简单的脚本来检查是否安装了特定程序,如果安装了则 return 该程序的版本号。

我已经能够 运行 脚本并且能够 return 一个二进制值,无论是否安装了程序,但不确定如何 return 已安装程序的版本号。

如果程序已安装,我将 post 所做的就是我对 return 所做的,然后需要帮助才能获得版本号。

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

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
    }
}

如果您想查看所有节目,则无需添加参数。只需将其输出通过管道传输到 Format-Table。 Format-Table 只是在项目不再是您期望的对象,而是 table 对象的地方做了一些奇怪的事情。以下是我的处理方式:

Get-InstalledProgram | Format-Table -Autosize

如果要搜索节目,请添加参数。您会在上面看到我为 ProgramName 添加了一个参数。它将此术语与注册表项的 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  

如果您只想获取版本,我建议您将输出通过管道传输到 Select-Object -ExpandProperty DisplayVersion

PS C:\> Get-InstalledProgram -ProgramName 'Java 8' | Select-Object -ExpandProperty DisplayVersion
8.0.1810.25

如果您希望该函数查找特定的已安装程序而不是 returning (table) 格式的字符串,那么您可以简单地执行以下操作:

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"

这将 return $null 未找到时,或版本为字符串 70.0.3538.67

无需在格式化 table 后进行匹配,您可以预先将 where 添加到 select 您需要的结果,然后直接从该对象获取 DisplayVersion。您可以进一步清理它以完全满足您的需要,但这里修改了您的代码以在找到应用程序时检索并显示该号码。尝试切换到错误名称以查看 else 结果:

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

已编辑: 根据建议将函数名称从 Check_Program_Installed 重命名为使用 PS 普通动词 Get

tl;dr

WindowsPowerShell[1]v5.1+,使用以下(在 both 32 位和 64 位已安装程序中搜索,如控制面板中所示):

Get-Package -ProviderName Programs -IncludeWindowsInstaller '*Google Chrome*' |
  ForEach-Object Version

注意:32-bit-only HKEY_LOCAL_MACHINE:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall 注册表项可能比控制面板显示的条目更具体 - 我不清楚为什么,但可能是复合视图在控制面板中就足够了。

应用于您的示例:

PS> (Get-Package -ProviderName Programs -IncludeWindowsInstaller '*Google Chrome*').Version
70.0.3538.67

至于你试过的

由于您专门检查 Wow6432Node 注册表项分支,您只检查已安装的 32 位 程序.

因此,您的函数的更好名称是 Check_32BitProgram_Installed,或者更符合函数的意图,使用 approved PowerShell verbGet-32BitProgramVersion.

或者,命名函数 Get-ProgramVersion 并查看 both 32 位和 64 位位置并按 [=31= 中所示处理结果] 有用的答案:

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*,
                 HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*

根据您问题的通用标题,以上是一个解决方案,它实质上是搜索已安装的应用程序列表,您将在控制面板 > 程序 > 程序和功能 (appwiz.cpl) 中看到,其中包括32 位和 64 位应用程序:

Windows PowerShell v5.1 带有 PackageManagement 模块 和一个 Programs 包提供程序[1] 允许通过 Get-Package cmdlet 检查已安装的程序;在 PSv3 和 PSv4 中,可以 manually install it.

列出已安装的程序(显示有删节的示例输出):

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                                                                      
# ...

输出 objects 的类型为 [Microsoft.PackageManagement.Packaging.SoftwareIdentity],它具有 .Name.Version 属性,可以实现上述解决方案。

Programs 包提供程序支持两个动态选项(特定于该提供程序的选项):

    需要
  • -IncludeWindowsInstaller 才能使报告的程序列表与控制面板显示的相匹配。

  • -IncludeSystemComponent,相比之下,报告的组件显示在控制面板中。


[1] 不幸的是,底层 Programs 包提供程序 在 PowerShell Core 中不可用 从 v7.0 开始在 Windows - 我不清楚这是 not-yet 情况还是永远不会 - 请参阅 GitHub issue #13225.