Lijst met geïnstalleerde software weergeven met PowerShell: Een gratis tool

Als je een systeembeheerder bent, is een van je taken het installeren, upgraden en verwijderen van software van veel systemen. Wat als ik je zou vertellen dat je niet meer handmatig naar geïnstalleerde software op elk systeem hoeft te zoeken? Je kunt eigenlijk geïnstalleerde software lijsten met PowerShell!

In deze blogpost ga ik je laten zien hoe je geïnstalleerde software kunt lijsten met PowerShell op je lokale machine en op veel computers tegelijk.

Listing installed software with PowerShell script

Merk op dat sommige artikelen je kunnen vertellen om zoiets te doen als Get-WmiObject -Class win32_product. Doe dat niet. Leer hier waarom hier.

Geïnstalleerde Software en het Register

Voor referentie, geïnstalleerde software bestaat op drie locaties:

  • het 32-bits systeemregister voor het verwijderen van software
  • het 64-bits systeemregister voor het verwijderen van software
  • het register voor het verwijderen van software van elk gebruikersprofiel.

Elke softwarevermelding wordt doorgaans gedefinieerd door de unieke wereldwijde identificatie (GUID) van de software. De binnenkant van de GUID-sleutel bevat alle informatie over dat specifieke stuk software. Om een volledige lijst te krijgen, moet PowerShell elk van deze sleutels doorlopen, elke registerwaarde lezen en de resultaten doorzoeken.

Aangezien de code om deze waarden correct te parsen veel meer is dan een enkel artikel kan bevatten, heb ik een functie genaamd Get-InstalledSoftware vooraf gebouwd om geïnstalleerde software te vermelden met PowerShell die al die code voor je omvat, zoals je hieronder kunt zien die geïnstalleerde programma’s op een computer vermeldt.

function Get-InstalledSoftware {
    <#
	.SAMENVATTING
		Retourneert een lijst van alle geïnstalleerde software op een Windows-computer.
	.VOORBEELD
		PS> Get-InstalledSoftware
		
		Dit voorbeeld haalt alle geïnstalleerde software op de lokale computer op.
	.PARAMETER ComputerName
		Als u een externe computer bevraagt, gebruik dan hier de computernaam.
	
	.PARAMETER Name
		De titel van de software waarop u de zoekopdracht wilt beperken.
	
	.PARAMETER Guid
		De software-GUID waarop u de zoekopdracht wilt beperken
	#>
    [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() ## Sommige registerwaarden hebben achterliggende spaties.
                                        } else {
                                            $output[$ValName] = $ValData.Trim() ## Sommige registerwaarden hebben achterliggende spaties
                                        }
                                    }
                                }
                                $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)"
        }
    }
}

Zodra je deze functie kopieert en plakt in je PowerShell-console of toevoegt aan je script, kun je deze aanroepen door een specifieke computernaam te gebruiken met de ComputerName-parameter.

Geïnstalleerde software vermelden met PowerShell

PS> Get-InstalledSoftware -ComputerName XXXXX

Als je dit doet, krijg je een object terug voor elk stuk software dat is geïnstalleerd. Je kunt een schat aan informatie krijgen over welke software dan ook is geïnstalleerd.

Als je van tevoren de naam van de software weet, kun je ook de parameter Naam gebruiken om alleen de software te beperken die overeenkomt met die waarde.

Bijvoorbeeld, misschien wil je alleen controleren of Microsoft Visual C++ 2005 Redistributable (x64) is geïnstalleerd. Je zou eenvoudigweg deze waarde gebruiken als de parameter Naam, zoals hieronder wordt getoond.

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

Samenvatting

Door PowerShell te gebruiken om geïnstalleerde software te verkrijgen, kun je een volledig gratis tool bouwen die jij en je team kunnen gebruiken om eenvoudig geïnstalleerde software op veel Windows-computers tegelijk te vinden!

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