AppWiz.cpl in PowerShell


Every so often, I need to find an installed program.  Until now, I’ve just been typing appwiz.cpl in my cmd.exe or PowerShell.exe window, but that’s inefficient.  Moreover, when I have to scan for the given build of a product deployed across the lab, that’s just painful.

 

Get-InstalledMsi | ? { $_.displayname -match ‘office’ } | Select-Object -Property computername,
  displayname, displayversion | fl

ComputerName   : TIMDUNN-W520
DisplayName    : Microsoft Visual Studio 2010 Tools for Office Runtime (x64)
DisplayVersion : 10.0.40303

ComputerName   : TIMDUNN-W520
DisplayName    : Microsoft Office Professional Plus 2013 – en-us
DisplayVersion : 15.0.4496.1000

(etc.)

Here’s the function.

function Get-InstalledMsi {
     param (
         [String[]]$computerName = @( $env:computerName )
     );
    
     try {
         foreach ($computer in $computerName) {
        
             # open remote registry
             $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(‘LocalMachine’, $computer);
             $regKey = $reg.OpenSubKey(‘Software\Microsoft\Windows\CurrentVersion\Uninstall’);
            
             # if successful
             if ($regKey) {
            
                 # get list of all installed programs
                 $installed = $regKey.GetSubKeyNames() | % {
                     $output = New-Object -TypeName PsObject;
                     Add-Member -MemberType ScriptMethod -Name AddNote -value { 
                         Add-Member -MemberType NoteProperty -Name $args[0] -Value $args[1] -InputObject $this | Out-Null
                     } -InputObject $output | Out-Null;
                    
                     $output.AddNote(‘ComputerName’, $computer);
                     $subkey = $regKey.OpenSubKey($_);
                     if ($subkey) {
                         $subkey.GetValueNames() | % { if ($_) { $output.AddNote($_, $subkey.GetValue($_)); } }
                         if ($output.DisplayName) { $output; }
                     }
                 }
                
                 #get list of all properties from all installed programs
                 $property = @();
                 $installed | % {
                     Get-Member -InputObject $_ -MemberType NoteProperty | % { if ([array]::IndexOf($property, $_.name) -eq -1) { $property += $_.name; } }
                 }
                
                 #output list of all installed programs with all properties from above.
                 $installed | % {
                     $output = $_;
                     $property | % { if ($output.$_ -eq $null) { $output.AddNote($_, $null); } }
                     $output;
                 }
             }
         }
     }
     catch  { Write-Warning “Insert error handling here.” }
}

Comments (2)

  1. RY says:

    How does this function works? can't run it directly…?

  2. timid says:

    You should just be able top copy/paste it into the PSH window, then call it.  The sample line:

    Get-InstalledMsi | ? { $_.displayname -match 'office' } | Select-Object -Property computername, displayname, displayversion | fl

    … includes a bunch of post-processing to filter it so you don't get spammed with screen after screen of data.  Specifically, it returns anything installed that has 'office' in the name.  If you don't have Office (or Visual Studio Pro/Ultimate) installed, it won't return anything.