Список установленного программного обеспечения с использованием PowerShell: бесплатный инструмент

Если вы являетесь системным администратором, одной из ваших задач является установка, обновление и удаление программного обеспечения с большого количества систем. Что если бы я сказал вам, что вам больше не нужно подключаться к каждой машине и проверять установленное программное обеспечение вручную? Вы можете фактически получить список установленного программного обеспечения с помощью PowerShell!

В этом блоге я покажу вам, как получить список установленного программного обеспечения с помощью PowerShell на вашей локальной машине и сразу на множестве компьютеров.

Listing installed software with PowerShell script

Обратите внимание, что некоторые статьи могут советовать вам сделать что-то вроде Get-WmiObject -Class win32_product. Не делайте этого. Узнайте почему здесь.

Установленное программное обеспечение и реестр

Для справки, установленное программное обеспечение находится в трех местах:

  • реестре удаления 32-битной системы
  • реестре удаления 64-битной системы
  • реестре удаления профиля каждого пользователя.

Каждая запись программного обеспечения обычно определяется идентификатором глобальной уникальности программы (GUID). Внутри ключа GUID содержится вся информация о конкретном программном продукте. Для получения полного списка PowerShell должен перечислить каждый из этих ключей, прочитать каждое значение реестра и проанализировать результаты.

Поскольку код для правильного разбора этих значений значительно превышает объем одной статьи, я предварительно создал функцию под названием Get-InstalledSoftware для перечисления установленного программного обеспечения с помощью PowerShell, которая упаковывает весь этот код для вас, как вы можете видеть ниже, перечисляя установленные программы на компьютере.

function Get-InstalledSoftware {
    <#
	.СИНОПСИС
		Получает список всего установленного программного обеспечения на компьютере под управлением Windows.
	.ПРИМЕР
		PS> Get-InstalledSoftware
		
		В этом примере извлекается вся установленная программная платформа на локальном компьютере.
	.ПАРАМЕТР ComputerName
		Если происходит запрос к удаленному компьютеру, используйте здесь его имя.
	
	.ПАРАМЕТР Name
		Заголовок программного обеспечения, по которому вы хотели бы ограничить запрос.
	
	.ПАРАМЕТР Guid
		Идентификатор программного обеспечения, по которому вы хотели бы ограничить запрос
	#>
    [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() ## Некоторые значения в реестре имеют завершающие пробелы.
                                        } else {
                                            $output[$ValName] = $ValData.Trim() ## Некоторые значения в реестре имеют завершающие пробелы
                                        }
                                    }
                                }
                                $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 одновременно!

Source:
https://adamtheautomator.com/powershell-list-installed-software/