检查是否安装了特定版本的程序
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 verb、Get-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.
我正在尝试创建一个非常简单的脚本来检查是否安装了特定程序,如果安装了则 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 verb、Get-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.