Get-RemoteProgram Get list of installed programs on remote or local computer

This script generates a list by querying the registry and returning the installed programs of a local or remote computer. It allows for retrieval of additional properties such as the uninstall string of an application as well.

4.4 Star
134,653 times
Add to favorites
Operating System
E-mail Twitter Digg Facebook
  • Thanks a lot, but the -Property parameter is very annoying
    2 Posts | Last post February 19, 2016
      Powershell is really great, because using
      … | Select-Object -Property *
      Users automatically gets all available properties.
      Your concept forces your users to reverse-engineer your script and then create a list of all existing uninstall-registry-values to get a list of all valid properties.
      Therefore I hope you don't intruduce a new paradigm which is very annoying. I assume you tried to optimize a performance problem which usually does not exist.
      I'm very sorry for this judgment.
      Kind regards,
    • Hello Tom,
      I am sorry to hear that you feel the script is not providing the output you expected. Just to make sure I understand you correctly, could you please explain what kind of output you expect from the script and how this is not matching.
      The reason I implemented the -Property functionality is because the keys in the registry can be different for each installed program, as manufactures can add their own registry keys. So that leaves us with two possible scenarios, either assure that every entry gets each possible property that is available in the registry, resulting in 100s of properties per object. Or we decide to define the properties per object based on what is available in the registry, but that would leave us with a collection of objects of which the properties do not match and therefore could not be placed in a csv file for example.
  • Script executes, but returns no data
    6 Posts | Last post January 05, 2016
    • Just downloaded this, and tried it out.
      I've opened a powershell console as an administrator on my own workstation and then ran it like so:
      .\Get-RemoteProgram.ps1 -computername remote-computer
      and it doesn't give any errors - just goes back to the prompt. I've dot-sourced it, and tried to run it without a computername to get my local software listing, but get the same results.
    • Could you try to first dot source the script and then access the function, try the following code:
      . .\Get-RemoteProgram.ps1
      Get-RemoteProgram -computername remote-computer
    • Was able to get a local listing when I used ". .\Get-RemoteProgram.ps1;Get-RemoteProgram", and after that in the same session was also able to get a local listing with just Get-RemoteProgram, but thereafter in the same session got an error with "Get-RemoteProgram -computername <remotecomputer>":
      Exception calling "OpenRemoteBaseKey" with "2" argument(s): "The network path was not found.
      At C:\BatchFiles\Get-RemoteProgram.ps1:73 char:13
      +             $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microso ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
          + FullyQualifiedErrorId : IOException"
      I also tried it with "get-adcomputer <computername> | Get-RemoteProgram" and also just <computername> | Get-RemoteProgram" and had no luck either way.
    • Update:
      My failures above are against a Win7 machine that is domain joined. I have just now also tried against a Server 2012 R2 Terminal Server and it worked as advertised, but against a Windows 8.1 machine it fails.
    • OK - I figured some of it out. The Remote Registry service wasn't turned on for the workstations. What I can't explain is why it would be turned on for a TS server, and not for the workstations.
      Any thoughts on that?
    • It depends on how the workstations were installed, you can define which services are enabled and disabled during and after installation. If you would like to ensure which services are enabled on workstations you could use group policy if you are in a domain environment. Alternative options are:
      - Use a Configuration Management tool to configure workstations, for example: Configuration Manager 2012R2
      - Use DSC to configure workstations
      - Create a templatedisk and deploy workstations from this template
  • Get Installed program of computer in LAN
    2 Posts | Last post December 24, 2015
    • Hi every one!
      I have a mission that to check all software that installed in client computer in AD from a list ( csv, excel), for example Team Viewer and export to output file CSV . Please help me how to do ? 
    • You could do something along these lines:
      . .\Get-RemoteProgram.ps1
      Get-Content -Path C:\ComputerList.Txt | ForEach-Object {
          Get-RemoteProgram -ComputerName $_
      } | Export-Csv -Path C:\InstalledPrograms.csv -NoTypeInformation
  • how can I run this against an array containing several computernames?
    3 Posts | Last post December 07, 2015
    • for example:
      $computers = Get-ADComputer -Filter {OperatingSystem -Like "Windows 7*"} -Property * | select-object Name
      I think I need a foreach of some kind so I can execute:
      Get-RemoteProgram -Computername $computers | select-object Programname,Computername | Where-Object -Property Programname 
      any tips?
    • I may have figured it out:
      foreach ($i in $args)
      {Get-ADComputer -Filter {OperatingSystem -Like "Windows 7*"} -Property * | select-object Name}
      Get-RemoteProgram -Computername $i | select-object Programname,Computername 
    • To simplify your code you could also do something along these lines:
      Get-ADComputer -Filter {OperatingSystem -Like "Windows 7*"} | Select-Object -ExpandProperty Name | Get-RemoteProgram | Select-Object ProgramName,ComputerName
  • Weird, Get-RemoteProgram does not work
    2 Posts | Last post November 11, 2015
    • I've updated the help files but can't find Get-RemoteProgram because I am thrown the error that it is not a cmdlet, function, or operable program. Why? I have Powershell 4.0
    • Can you navigate to the folder in which the script is stored. When you are in that folder can you execute the following to verify if the file is still functional:
      . .\Get-RemoteProgram.ps1;Get-RemoteProgram
      What this does is dot source the script that makes the Get-RemoteProgram function available. If you would like to ensure that the function is always available, then you could load this function on start up by adding this to your personal PowerShell profile.
  • Where to place computers.text file
    6 Posts | Last post October 23, 2015
    • Dumb question, where do I place text file that the scripts reads when it is executed? 
    • You can place the text file wherever you prefer, if you want to use a text file to provide the computer names you could execute the script with something along these lines:
      . .\Get-RemoteProgram.ps1
      Get-Content -Path C:\YourPath\YourInputFile.txt | Get-RemoteProgram
    • Thanks Alot Japp! 
      Another question; is there a way to add, not only the version and versionmajor, but also the OS of the system in question? 
    • Sure that's possible, that information cannot be retrieved by this function. So you could do a WMI query to retrieve that information, here is an example of how to do this:
      . .\Get-RemoteProgram.ps1
      Get-Content -Path C:\YourPath\YourInputFile.txt | ForEach-Object {$Version = (Get-WmiObject -ComputerName $_.ComputerName -Query 'Select Version From Win32_OperatingSystem').Version;Get-RemoteProgram -ComputerName $_ -Property VersionMajor,DisplayVersion | Select-Object *,@{name='OSVersion';expression={$Version}}}
    • what line of the script would I inject this extra code into? would I still be able to use the export feature once its done? 
      Basically, I would like to use the script to be able to pull all the information it already can, plus also identifying OS version. then export this to a list. 
      You have been a great deal of help already! Thanks for your contributions!
    • Hello Agent Blah,
      You do not have to update the script, you can simply execute the code I posted above and the script will get the additional output you require. Basically I just do two things, first I assign the current computer's Build and version number to the $Version variable:
      $Version = (Get-WmiObject -ComputerName $_.ComputerName -Query 'Select Version From Win32_OperatingSystem').Version
      Then I use calculated properties to add this as an additional property:
      | Select-Object *,@{name='OSVersion';expression={$Version}}
      So you can simply execute the code in my previous example you should get the output you requested.
  • Adding the ProductCode
    2 Posts | Last post October 08, 2015
    • Hi Jaap,
      Thank you for sharing this snippet. I have made a minor modification that I thought I should share back. I've run into a situation where a particular UninstallString is incorrect, therefore I needed the ProductCode/PackageID to invoke the correct MSIExec command to remove the program.
      Unfortunately this information is not duplicated in the Subkey so using the -Property tag did not work. However in this script you do have the Subkey name in your hand, as per the MSDN documentation this should be the ProductCode/PackageID (in practice it seems like not everyone follows this, but if its an actual Windows Installer/MSI it will).
      Simply modify the $SelectProperty to contain a new property 'ProductCode' and then add $HashProperty.ProductCode = "$_" after the program name is assigned and you should have what you want.
      You could get a little more tricky and check for the property dynamically in the foreach loop, but this is the path of least resistance.
    • Hello aolszowka,
      I can see how this could be useful, I would actually like to take it one step further and add in a switch that will expose the registry key. This would give you the ability to retrieve the product key from that and it also shows which part of the registry this information is retrieved from SYSWOW or default path.
      Would that be an interesting addition for you?
  • Can you tell me what I need to add to the script in order to word-wrap the ProgramName? Thank you in advance.
    2 Posts | Last post September 21, 2015
    • I'm somewhat new to PowerShell. I was trying different things but could not come up with a good solution. Thank you.
    • Hello Carlos,
      I am afraid I am not sure what you mean by word wrapping in this context. Can you give an example of the output you are currently getting and an example of what you would like to be getting. If you provide me with that information I will most likely be able to help you out with this.
  • How to get the version of only specific Program from this function
    5 Posts | Last post September 03, 2015
    • I am trying with the below code but not getting the result, can u please help!
       Get-InstalledProgram -Property DisplayVersion -ComputerName (Get-Content .\serverlist.txt) -ErrorAction SilentlyContinue | Where-Object {[string]$_.SystemComponent -ne 1 -and ![string]$_.IsMinorUpgrade -and ![string]$_.ReleaseType -and ![string]$_.ParentDisplayName -a
      nd $_.ProgramName -like "*Endpoint*"}  | sort-Object ProgramName -ErrorAction SilentlyContinue
    • Please Note: i just changed get-remoteProgram to get-installedProgram :)
    • Hello Vicky,
      The script by default only retrieves the ProgramName and the ComputerName, any additional properties will have to be retrieved by using the -Property parameter like you were doing with DisplayVersion. Since you are using a Where-Object clause that includes additional properties you should also retrieve those from the registry.
      I rewrote your code to the following:
      Get-RemoteProgram -Property DisplayVersion,SystemComponent,IsMinorUpgrade,ReleaseType,ParentDisplayName -ComputerName (Get-Content .\serverlist.txt) | Where-Object {[string]$_.SystemComponent -ne 1 -and ![string]$_.IsMinorUpgrade -and ![string]$_.ReleaseType -and ![string]$_.ParentDisplayName -and $_.ProgramName -like "*Endpoint*"} | Sort-Object ProgramName
    • Thank you very much Jaap Brasser :)
    • No problem, happy to help. Cool avatar by the way :)
  • Get Version Number Too
    2 Posts | Last post August 13, 2015
    • I changed line 65 and added line 86 as follows:
      Line 65:
      $SelectProperty = @('ProgramName','ProgramVersion','ComputerName')
      Line 86:
      $HashProperty.ProgramVersion = ($DisplayName = ($RegBase.OpenSubKey("$CurrentReg$_")).GetValue('DisplayVersion'))
    • The cool thing about the script is that this is already supported without the need to change the script. All you have to do is run the original script as it is posted here like this:
      Get-RemoteProgram -Property DisplayVersion
      This will get you the same result as editing the script. If it is required to name the column ProgramVersion then you could also do something along these lines:
      Get-RemoteProgram -Property DisplayVersion | Select-Object -Property ProgramName,ComputerName,@{name=ProgramVersion;expression={$_.DisplayName}}
      Let me know how that works for you!
61 - 70 of 83 Items