PowerShell로 설치된 소프트웨어 목록 표시: 무료 도구

시스템 관리자이면 여러 시스템에서 소프트웨어를 설치, 업그레이드 및 제거하는 일 중 하나입니다. 하지만 더 이상 각 기계에 연결하여 수동으로 설치된 소프트웨어를 확인할 필요가 없다고 말하면 어떨까요? PowerShell을 사용하여 실제로 설치된 소프트웨어 목록을 작성할 수 있습니다!

이 블로그 포스트에서는 로컬 기기 및 여러 컴퓨터에서 PowerShell을 사용하여 설치된 소프트웨어 목록을 작성하는 방법을 안내하겠습니다.

Listing installed software with PowerShell script

일부 문서에서 Get-WmiObject -Class win32_product와 같은 작업을 수행하도록 안내하는 경우가 있습니다. 이렇게 하지 마세요. 여기에서 이유를 알아보세요.

설치된 소프트웨어 및 레지스트리

참고로, 설치된 소프트웨어는 세 가지 위치에 있습니다.

  • 32비트 시스템의 언인스톨 레지스트리 키
  • 64비트 시스템의 언인스톨 레지스트리 키
  • 각 사용자 프로필의 언인스톨 레지스트리 키.

일반적으로 각 소프트웨어 항목은 소프트웨어의 전역 고유 식별자 (GUID)에 의해 정의됩니다. GUID 키 내부에는 해당 소프트웨어에 대한 모든 정보가 포함되어 있습니다. PowerShell에서 완전한 목록을 얻으려면 각 키를 열거하고 각 레지스트리 값에 대해 읽고 결과를 구문 분석해야 합니다.

이러한 값을 올바르게 구문 분석하는 코드는 단일 기사에 담을 수 있는 것보다 훨씬 많으므로, PowerShell을 사용하여 설치된 소프트웨어를 나열하는 Get-InstalledSoftware 함수를 미리 작성했습니다. 아래에서 볼 수 있듯이 이 코드는 모든 코드를 랩핑합니다. 컴퓨터에 설치된 프로그램을 나열합니다.

function Get-InstalledSoftware {
    <#
	.SYNOPSIS
		Windows 컴퓨터에 설치된 모든 소프트웨어 목록을 검색합니다.
	.EXAMPLE
		PS> Get-InstalledSoftware
		
		이 예제는 로컬 컴퓨터에 설치된 모든 소프트웨어를 검색합니다.
	.PARAMETER ComputerName
		원격 컴퓨터를 쿼리하는 경우 여기에 컴퓨터 이름을 사용합니다.
	
	.PARAMETER Name
		쿼리를 특정 소프트웨어 제목으로 제한하려는 경우 사용합니다.
	
	.PARAMETER Guid
		쿼리를 특정 소프트웨어 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/