Computer/Get-ProgramInstallInfo.ps1

# Copyright 2012 Aaron Jensen
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

function Get-ProgramInstallInfo
{
    <#
    .SYNOPSIS
    Gets information about the programs installed on the computer.
     
    .DESCRIPTION
    This function is the PowerShell equivalent of the Programs and Features UI.
 
    .OUTPUTS
    Carbon.Computer.ProgramInstallInfo.
 
    .EXAMPLE
    Get-ProgramInstallInfo
 
    Demonstrates how to get a list of all the installed programs, similar to what the Programs and Features UI shows.
 
    .EXAMPLE
    Get-ProgramInstallInfo -Name 'Google Chrome'
 
    Demonstrates how to get a specific program. If the specific program isn't found, `$null` is returned.
 
    .EXAMPLE
    Get-ProgramInstallInfo -Name 'Microsoft*'
 
    Demonstrates how to use wildcards to search for multiple programs.
    #>

    [CmdletBinding()]
    param(
        [string]
        # The name of a specific program to get. Wildcards supported.
        $Name
    )

    Set-StrictMode -Version 'Latest'

    if( -not (Test-Path -Path 'hku:\') )
    {
        $null = New-PSDrive -Name 'HKU' -PSProvider Registry -Root 'HKEY_USERS'
    }

    ('HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall','HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall','hku:\*\Software\Microsoft\Windows\CurrentVersion\Uninstall\*') |
        Where-Object { Test-Path -Path $_ -PathType Container } | 
        Get-ChildItem | 
        Where-Object { 
            $valueNames = $_.GetValueNames()

            [Microsoft.Win32.RegistryKey]$key = $_

            if( $valueNames -notcontains 'DisplayName' )
            {
                Write-Verbose ('Skipping {0}: DisplayName not found.' -f $_.Name)
                return $false
            }

            $displayName = $_.GetValue( 'DisplayName' )

            if( $valueNames -contains 'ParentKeyName' )
            {
                Write-Verbose ('Skipping {0} ({1}): found ParentKeyName property.' -f $displayName,$_.Name)
                return $false
            }

            if( $valueNames -contains 'SystemComponent' -and $_.GetValue( 'SystemComponent' ) -eq 1 )
            {
                Write-Verbose ('Skipping {0} ({1}): SystemComponent property is 1.' -f $displayName,$_.Name)
                return $false
            }

            return $true
        } |
        Where-Object { 
                if( $Name ) 
                { 
                    return $_.GetValue('DisplayName') -like $Name 
                } 
                return $true
            } | 
        ForEach-Object { New-Object 'Carbon.Computer.ProgramInstallInfo' $_ }
}