当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PowerShell 快速列出已安装的软件(30 秒内)

作者:精品下载站 日期:2024-12-14 20:48:51 浏览:16 分类:玩电脑

使用 PowerShell 快速列出已安装的软件(30 秒内)


如果您是系统管理员,您的工作之一就是在许多系统中安装、升级和删除软件。如果我告诉您您不必再连接到每台计算机并手动检查已安装的软件怎么办?您实际上可以使用 PowerShell 列出已安装的软件!

在这篇博文中,我将向您展示如何使用 PowerShell 同时列出本地计算机和大量计算机上已安装的软件。

[玩转系统] 使用 PowerShell 快速列出已安装的软件(30 秒内)

请注意,有些文章可能会告诉您执行诸如 Get-WmiObject -Class win32_product 之类的操作。不要那样做。在这里了解原因。

安装的软件和注册表

作为参考,已安装的软件存在于三个位置:

  • 32位系统卸载注册表项
  • 64位系统卸载注册表项
  • 每个用户配置文件的卸载注册表项。

每个软件条目通常由软件的全局唯一标识符 (GUID) 定义。 GUID 密钥的内部包含有关该特定软件的所有信息。要获得完整的列表,PowerShell 必须枚举每个键、读取每个注册表值并解析结果。

由于正确解析这些值的代码远远超出一篇文章所能容纳的范围,因此我预先构建了一个名为 Get-InstalledSoftware 的函数,用于列出已安装的软件,其中 PowerShell 为您封装了所有这些代码正如您在下面看到的,列出了计算机上已安装的程序。

function Get-InstalledSoftware {
    <#
	.SYNOPSIS
		Retrieves a list of all software installed on a Windows computer.
	.EXAMPLE
		PS> Get-InstalledSoftware
		
		This example retrieves all software installed on the local computer.
	.PARAMETER ComputerName
		If querying a remote computer, use the computer name here.
	
	.PARAMETER Name
		The software title you'd like to limit the query to.
	
	.PARAMETER Guid
		The software GUID you'e like to limit the query to
	#>
    [CmdletBinding()]
    param (
		
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$ComputerName = $env:COMPUTERNAME,
		
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]$Name,
		
        [Parameter()]
        [guid]$Guid
    )
    process {
        try {
            $scriptBlock = {
                $args[0].GetEnumerator() | ForEach-Object { New-Variable -Name $_.Key -Value $_.Value }
				
                $UninstallKeys = @(
                    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall",
                    "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
                )
                New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS | Out-Null
                $UninstallKeys += Get-ChildItem HKU: | where { $_.Name -match 'S-\d-\d+-(\d+-){1,14}\d+$' } | foreach {
                    "HKU:$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Uninstall"
                }
                if (-not $UninstallKeys) {
                    Write-Warning -Message 'No software registry keys found'
                } else {
                    foreach ($UninstallKey in $UninstallKeys) {
                        $friendlyNames = @{
                            'DisplayName'    = 'Name'
                            'DisplayVersion' = 'Version'
                        }
                        Write-Verbose -Message "Checking uninstall key [$($UninstallKey)]"
                        if ($Name) {
                            $WhereBlock = { $_.GetValue('DisplayName') -like "$Name*" }
                        } elseif ($GUID) {
                            $WhereBlock = { $_.PsChildName -eq $Guid.Guid }
                        } else {
                            $WhereBlock = { $_.GetValue('DisplayName') }
                        }
                        $SwKeys = Get-ChildItem -Path $UninstallKey -ErrorAction SilentlyContinue | Where-Object $WhereBlock
                        if (-not $SwKeys) {
                            Write-Verbose -Message "No software keys in uninstall key $UninstallKey"
                        } else {
                            foreach ($SwKey in $SwKeys) {
                                $output = @{ }
                                foreach ($ValName in $SwKey.GetValueNames()) {
                                    if ($ValName -ne 'Version') {
                                        $output.InstallLocation = ''
                                        if ($ValName -eq 'InstallLocation' -and 
                                            ($SwKey.GetValue($ValName)) -and 
                                            (@('C:', 'C:\Windows', 'C:\Windows\System32', 'C:\Windows\SysWOW64') -notcontains $SwKey.GetValue($ValName).TrimEnd('\'))) {
                                            $output.InstallLocation = $SwKey.GetValue($ValName).TrimEnd('\')
                                        }
                                        [string]$ValData = $SwKey.GetValue($ValName)
                                        if ($friendlyNames[$ValName]) {
                                            $output[$friendlyNames[$ValName]] = $ValData.Trim() ## Some registry values have trailing spaces.
                                        } else {
                                            $output[$ValName] = $ValData.Trim() ## Some registry values trailing spaces
                                        }
                                    }
                                }
                                $output.GUID = ''
                                if ($SwKey.PSChildName -match '\b[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}\b') {
                                    $output.GUID = $SwKey.PSChildName
                                }
                                New-Object -TypeName PSObject -Prop $output
                            }
                        }
                    }
                }
            }
			
            if ($ComputerName -eq $env:COMPUTERNAME) {
                & $scriptBlock $PSBoundParameters
            } else {
                Invoke-Command -ComputerName $ComputerName -ScriptBlock $scriptBlock -ArgumentList $PSBoundParameters
            }
        } catch {
            Write-Error -Message "Error: $($_.Exception.Message) - Line Number: $($_.InvocationInfo.ScriptLineNumber)"
        }
    }
}

将此函数复制并粘贴到 PowerShell 控制台或将其添加到脚本中后,您可以使用带有 ComputerName 参数的特定计算机名称来调用它。

使用 PowerShell 列出已安装的软件

PS> Get-InstalledSoftware -ComputerName XXXXX

当您执行此操作时,您将为每个已安装的软件获取一个对象。无论安装什么软件,您都可以获得有关此的大量信息。

如果您提前知道软件标题,还可以使用 Name 参数来限制仅匹配该值的软件。

例如,也许您只想检查是否安装了 Microsoft Visual C++ 2005 Redistributable (x64)。您只需将其用作 Name 参数值,如下所示。

PS> Get-InstalledSoftware -ComputerName MYCOMPUTER -Name 'Microsoft VisualC++ 2005 Redistributable (x64)'

概括

使用 PowerShell 获取已安装的软件,您可以构建一个完全免费的工具,您和您的团队可以使用该工具轻松地在许多 Windows 计算机上同时查找已安装的软件!

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯