Query registry for installed software Hoping someone can help me out with the two aspects of my script that I think is causing the most performance hindrance. Recreating the Array $Result and using the Get-ItemProperty on each and every key to get the required information. Is there a better way to accomplish this task?

Function Get-SoftwareList {
    &lt;#
    #&gt;
    Param()

    New-Variable -Force -ErrorAction SilentlyContinue -Name Result   -Value @()
    New-Variable -Force -ErrorAction SilentlyContinue -Name Function -Value @{}
    $Function.Exclusions = (
        "Security Update for Windows",
        "Security Update for Microsoft",
        "Update for Windows",
        "Update for Microsoft",
        "Hotfix for Windows",
        "Update for Skype",
        "Security Update for Skype"
    )
    If([IntPtr]::Size -eq 8){             
        $Function.OSArch='64-bit' 
    } Else{             
        $Function.OSArch='32-bit'             
    }

    $Function.Registry = Get-Childitem -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall"
    IF ($Function.OSArch -EQ "64-bit") {
        $Function.Registry += Get-ChildItem -Path "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
    }

    ForEach ($Key in $Function.Registry) {
        $Key = Get-ItemProperty -Path Registry::$Key
        IF ($Key.DisplayName.length -NE 0) {
            ForEach ($Exclusion in $Function.Exclusions) {
                If ($Key.DisplayName.StartsWith($Exclusion) -EQ $True) { 
                    $Skip = $True
                    Break
                } Else {
                    $Skip = $False
                }
            }
            IF ($Skip -EQ $False) {
                $Result += New-Object PSObject -Property @{ 
                    DisplayName     = $Key.DisplayName
                    Version         = $Key.DisplayVersion 
                    UninstallString = $Key.UninstallString
                    Publisher       = $Key.Publisher
                    #ModifyPath      = $Key.ModifyPath
                    InstallDate     = $Key.InstallDate
                }
            }
        }
    }
    Return $Result
}
Finding a very quick/reliable solution was actually significantly harder than I was expecting but this is the best I can come up with. It lists about ~130 applications in about 22ms on my computer.

    Function Get-InstalledSoftware {
    Param (
        [Array]$Properties = @('DisplayName','DisplayVersion')
    )
    $Keys = "Software\Microsoft\Windows\CurrentVersion\Uninstall","SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
    $Result = New-Object -TypeName 'System.Collections.ArrayList'
    $BaseKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$ENV:ComputerName)
    ForEach($Key in $Keys) {
        $RegKey = $BaseKey.OpenSubkey($key)
        If($RegKey -ne $null) {
            ForEach($subName in $RegKey.getsubkeynames()) {
                foreach($sub in $RegKey.opensubkey($subName)) {
                    [string]$Name = $sub.getvalue("displayname")
                    If ($Name.trim().Length -gt 0) {
                        $HashProperty = @{}
                        ForEach ($CurrentProperty in $Properties) {
                            $HashProperty.$CurrentProperty = $sub.GetValue($CurrentProperty)
                        }#End-ForEach
                        $Result.add([psCustomObject]$HashProperty)
                    }#End-IF
                }#End-ForEach
            }#End-Foreach
        }#End-IF
    }#End-ForEach
    $Result
}


The new script is not only significantly more flexible, but also significantly faster than previous solutions. 

Measure-Command {
    for($i = 0; $i -lt 100; $i++) {
        Get-InstalledSoftware99 -Properties DisplayName,UninstallString,DisplayVersion
    }
}

Measure-Command {
    for($i = 0; $i -lt 100; $i++) {
        Get-SoftwareList
    }
}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 925
Ticks             : 9259570
TotalDays         : 1.07170949074074E-05
TotalHours        : 0.000257210277777778
TotalMinutes      : 0.0154326166666667
TotalSeconds      : 0.925957
TotalMilliseconds : 925.957

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 14
Milliseconds      : 695
Ticks             : 146959970
TotalDays         : 0.00017009255787037
TotalHours        : 0.00408222138888889
TotalMinutes      : 0.244933283333333
TotalSeconds      : 14.695997
TotalMilliseconds : 14695.997