3

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

我已经能够运行脚本并且能够在是否安装程序时返回二进制值,但不确定如何返回已安装程序的版本号。

如果安装了程序,我将发布的只是我正在做的返回,并且需要帮助才能获得版本号。

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

在此处输入图像描述

4

4 回答 4

5

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

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"

这将$null在找不到时返回,或者版本为字符串70.0.3538.67

于 2018-10-17T14:09:28.753 回答
5

而不是在格式化表格后进行匹配,您可以添加一个 where 以预先选择您需要的结果,然后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

于 2018-10-17T14:11:02.640 回答
3
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 在项目不再是您期望的对象,而是表格对象的地方做了一些奇怪的事情。以下是我将如何处理:

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
于 2018-10-17T14:09:20.893 回答
2

tl;博士

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

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

注意:仅 32 位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,或者更符合函数的意图,使用批准的 PowerShell 动词, Get-32BitProgramVersion.

或者,命名函数Get-ProgramVersion并查看32 位64 位位置并处理结果,如TheoKevin M. LapioShawn Esterman 的有用答案所示:

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-Packagecmdlet 检查已安装的程序;在 PSv3 和 PSv4 中,可以手动安装它

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

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

输出对象的类型为[Microsoft.PackageManagement.Packaging.SoftwareIdentity],具有.Name.Version属性,可启用上述解决方案。

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

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

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


[1] 不幸的是,从 v7.0开始,Windows 上的 PowerShell Core中提供底层Programs包提供程序- 我不清楚这是否还没有出现,或者永远不会出现 - 请参阅GitHub 问题 #13225

于 2018-10-17T16:15:29.930 回答