title: Finding ALL installed applications with PowerShell?
body: <p>I am trying to use Windows PowerShell 2.0 to find an installed application. I have tried two methods, one using WMI and one using the Registry. Both methods are able to bring up a large list of installed applications and components, however neither one seems to bring up the application I am interested in. </p>
  
  <p>I am specifically looking for CruiseControl.NET. It appears in the list of applications in the Programs and Features control panel applet. I know for a fact that it is currently installed, since I just uninstalled and reinstalled it to start fresh. Neither of the following methods seem to work, however (they succeed, but return no results):</p>
  
  <p><strong>Registry Search Approach</strong></p>
  
  <p>Looks in the registry <code>HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall</code> for application keys. Returns plenty if I remove the <em>where</em>, but it is missing quite a few applications that do appear in the windows programs and features control panel.</p>
  
  <pre><code>gci "hklm:\software\microsoft\windows\currentversion\uninstall" 
      | foreach { gp $_.PSPath } 
      | select DisplayVersion,InstallDate,ModifyPath,Publisher,UninstallString,Language,DisplayName 
      | where { $_.DisplayName -match "^Cruise*" }
  </code></pre>
  
  <p><strong>WMI Approach</strong></p>
  
  <p>Also returns plenty, however, based on the documentation for the Win32_Product object, they are only MSI installed applications. Many applications are missing, I'm guessing because they are not MSI. The CruiseControl.NET installer is the NSIS (NullSoft Installation System)...since it doesn't appear here, I am guessing that it doesn't use MSI at all, however I am curious if there is another way to use WMI to find ANY/ALL installed applications, regardless of whether they used MSI or not.</p>
  
  <pre><code>gwmi -namespace "root\cimv2" -class "Win32_Product" 
      | select Name,Vendor,Version,IdentifyingNumber 
      | where { $_.Name -match "^Cruise*" }
  </code></pre>
  
  <p>Finding the application via the registry does not do me a whole lot of good, really. Unless it also provides some way to find the applications uninstaller and the correct parameters to invoke it, which does not appear to always be the case. I would prefer to use WMI to find and uninstall the applications I need to uninstall, as that would not only allow me to use a single management interface for all of my scripts (WMI), but it should be easy for others to figure out how to maintain the scripts in the future since WMI is generally well documented.</p>