正在使用PowerShell中的注册表项安装软件,某些软件名称未显示

正在使用PowerShell中的注册表项安装软件,某些软件名称未显示,powershell,Powershell,我有一个脚本,可以使用注册表项获取所有已安装软件的列表。但是当我检查列表时,有些条目没有显示名称或版本。以下是我的脚本: ## Include CSV file of all computers with header "pc" $computers = Import-Csv "C:\Users\P1334126\Documents\Test.CSV" $array = @() #Define the variable to hold the loc

我有一个脚本,可以使用注册表项获取所有已安装软件的列表。但是当我检查列表时,有些条目没有显示名称或版本。以下是我的脚本:

## Include CSV file of all computers with header "pc"
$computers = Import-Csv "C:\Users\P1334126\Documents\Test.CSV"

$array = @()  
#Define the variable to hold the location of Currently Installed Programs
foreach($pc in $computers) {
    $computername=$pc.computername
    $UninstallKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
 
    #Create an instance of the Registry Object and open the HKLM base key
    $reg = [microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine', $computername)
  
    #Drill down into the Uninstall key using the OpenSubKey Method
    $regkey = $reg.OpenSubKey($UninstallKey) 
  
    #Retrieve an array of string that contain all the subkey names
    $subkeys = $regkey.GetSubKeyNames() 
  
    #Open each Subkey and use GetValue Method to return the required values for each
    foreach($key in $subkeys) {
        $thisKey=$UninstallKey + '\\' + $key 
        $thisSubKey=$reg.OpenSubKey($thisKey) 
        $obj = New-Object PSObject
        $obj | Add-Member -MemberType NoteProperty -Name 'ComputerName' -Value $computername
        $obj | Add-Member -MemberType NoteProperty -Name 'DisplayName' -Value $($thisSubKey.GetValue("DisplayName"))
        $obj | Add-Member -MemberType NoteProperty -Name 'DisplayVersion' -Value $($thisSubKey.GetValue("DisplayVersion"))
        $obj | Add-Member -MemberType NoteProperty -Name 'Publisher' -Value $($thisSubKey.GetValue("Publisher"))
        $array += $obj
    }
}

$array | Select-Object ComputerName, DisplayName, DisplayVersion, Publisher | Sort-Object -Property 
ComputerName | Out-File InstalledSoftware.txt
如下图所示,一些名称和版本有误,这有什么原因吗?谢谢你的帮助。

您确实应该避免使用
+=
语法收集数组中的内容,因为它会在每次迭代时完全重新创建数组。它会使代码速度变慢,并且会消耗内存。
此外,我建议您在使用完注册表项后关闭已打开的注册表项

至于输出,您目前正在将结果保存到一个简单的文本文件中,但我认为(因为您收集了漂亮的对象)输出到CSV文件会更好,因为这样可以将信息保留为可读数据,例如,您可以在Excel中打开

您的代码已修订:

# Include CSV file of all computers with header "pc"
$computers = Import-Csv "C:\Users\P1334126\Documents\Test.CSV"

# probe these two registry paths
$UninstallPaths = 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall',
                  'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'

# Collect info of Currently Installed Programs
$array = foreach ($pc in $computers) {
    $computername = $pc.computername

    # Create an instance of the Registry Object and open the HKLM base key
    $regHKLM = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computername)

    foreach ($UninstallKey in $UninstallPaths) {
        # Drill down into the Uninstall key using the OpenSubKey Method
        $regkey = $regHKLM.OpenSubKey($UninstallKey) 
        # the computer may not have the 'Wow6432Node' registry key
        if (!$regkey) { break }

        # Retrieve an array of string that contain all the subkey names
        $subkeys = $regkey.GetSubKeyNames() 

        # Open each Subkey and use GetValue Method to return the required values for each
        foreach($key in ($regkey.GetSubKeyNames())) {
            $thisPath   = Join-Path -Path $UninstallKey -ChildPath $key
            $thisSubKey = $regHKLM.OpenSubKey($thisPath) 
            # we want to output only if there is at least a DisplayName to show
            $displayName = $thisSubKey.GetValue("DisplayName")
            if (![string]::IsNullOrWhiteSpace($displayName)) {
                # output a PSObject to be collected in variable $array
                # the order of the properties also defines the order of the fields in the output
                [PsCustomObject] @{
                    ComputerName   = $computername
                    DisplayName    = $displayName
                    DisplayVersion = $thisSubKey.GetValue("DisplayVersion")
                    Publisher      = $thisSubKey.GetValue("Publisher")
                    # if you want to know the registry path aswell, uncomment the next entry
                    # RegistryPath   = $thisPath
                }
            }
            # close the subkey
            $thisSubKey.Close()
        }
        # close the $regKey
        $regkey.Close()
    }
    # close the base key
    $regHKLM.Close()
}

# sort on ComputerName
$array = $array | Sort-Object -Property ComputerName

# output on screen
$array | Format-Table -AutoSize

# or if you prefer
$array | Out-GridView -Title 'InstalledSoftware'

# output to CSV file you can open in Excel
$array | Export-Csv -Path 'InstalledSoftware.csv' -NoTypeInformation

您可以使用此列表而不是注册表来列出powershell 5.1中已安装的软件:

get-package

相当多的此类注册表项没有显示名称。这就是为什么访问该信息的代码通常包括类似>>
Where Object DisplayName-ne$null |
的内容,非常感谢!它现在运行得很好,非常感谢您的帮助和信息实际上有一个小问题,我也在2012R2和2008R2机器上安装了chrome,以及其他程序,如记事本+,但为什么不显示?@Keith请查看我编辑的版本。这将探测已安装软件的两个注册表项。第一个版本在64位机器上缺少'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'键hanks@Theo!它现在工作得很好