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
(64)
105,037 times
Add to favorites
Operating System
8/5/2019
E-mail Twitter del.icio.us Digg Facebook
Sign in to ask a question


  • how to interpret this result?
    2 Posts | Last post November 15, 2016
    • the script works fine, but when i execute for another pc, this result comes out:
      
      "Exception calling "OpenRemoteBaseKey" with "2" argument(s): "Attempted to perform an unauthorized operation."
      At C:\Users\M.Zeneli\Downloads\Get-RemoteProgram.ps1:91 char:13
      +             $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microso ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
          + FullyQualifiedErrorId : UnauthorizedAccessException"
    • It is likely that you have not given PowerShell permission to run the command on the remote computer. Try running the PowerShell ISE or prompt as Admin (right click on it). This assumes that you (as an individual) has rights to ask the remote computer for the information. For example, I am a tier 2 IT tech, I do not have the user permissions to request installed programs from a tier 3 server. My Admin credentials simply don't have the rights.  
  • PS Remote not allowed
    1 Posts | Last post November 03, 2016
    • Hi Thanks for a great job.
      I have a problem in my environment that is PS remote invoke commands are not allowed.
      Only way i can do remote PS requests is through get-wmiobject. And im really need a script like this to go through my clients installed program. Do you have any time to help me how this should look like
  • Full List in CSV
    1 Posts | Last post October 25, 2016
    • I have to get a list of specific software on my domain, namely software that costs money, or has specific activation counts per licence.  So far I have the following function combining another script I wrote to get all domain PC names, then "foreach" through the pc's and calls your script.  Is there an easier way you can think of?
      
      I currently have this code:
      
      function main() {
      
      	$computers = get-domaincomputers
      	foreach ($comp in $computers)
      	{
      		# Ping the PC first to check if it is alive.....
      		if (Test-Connection -BufferSize 32 -Count 1 -ComputerName $comp -Quiet)
      		{
      			#$pc_Active += $comp
      			Get-RemoteProgram -computername $comp -property Uninstallstring | Where-Object {($_.ProgramName -notmatch $RegEx) -and (-not $_.SystemComponent)} | Export-Csv -Path .\"$comp"_App_list.csv -NoTypeInformation
      		}
      	}
      	
      }
      
      also I want to take this instead of creating a file for each PC create one file with PC Name, Application, Uninstall Path
      
      any quick ideas on how to combine them all into one variable/array, then dump that to CSV?
  • Skipping connection fails
    4 Posts | Last post September 22, 2016
    • Hi Jaap,
      first of all, great, great job. It is very helpful!
      I have a list of computers in the network I'd like to scan.
      Though, not all of them are connected. How do I skip those instead of breaking a script?
      I'm running it:
      . .\Get-RemoteProgram.ps1
      Get-Content -Path 'C:\Users\User1\Desktop\computers.txt' | ForEach-Object {Get-RemoteProgram -ComputerName $_ -Property Uninstallstring | Select-Object -Property ComputerName,ProgramName,Uninstallstring} | Export-Csv -Path C:\Users\User1\Desktop\list.csv -NoTypeInformation
      It breaks whenever finds a machine offline in this very moment. I'd like to just skip it.
      Is it possible?
    • Hello JohnnieDoe1989,
      
      That should not be the case, the script should carry on after an error. Could you check the output of the following to confirm if your ErrorActionPreference is set to something other than continue:
      
      $ErrorActionPreference
      
      Another way is by setting your error action preference before running the script, for example:
      
      . .\Get-RemoteProgram.ps1
      $ErrorActionPreference = 'Continue'
      Get-Content -Path 'C:\Users\User1\Desktop\computers.txt' | ForEach-Object {Get-RemoteProgram -ComputerName $_ -Property Uninstallstring | Select-Object -Property ComputerName,ProgramName,Uninstallstring} | Export-Csv -Path C:\Users\User1\Desktop\list.csv -NoTypeInformation
      
      Let me know how that works for you.
      
      
      Regards,
      
      Jaap Brasser
      
    • Hmm. Maybe I'm just misinterpreting the error:
      
      Exception calling "OpenRemoteBaseKey" with "2" argument(s): "The network path was not found.
      "
      At C:\Users\User1\Desktop\Get-RemoteProgram.ps1:91 char:13
      +             $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microso ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
          + FullyQualifiedErrorId : IOException
       
      PS C:\Users\User1\Desktop> $ErrorActionPreference
      Continue
    • All right, I guess that's not the reason. Someone already had this problem:
      
      Written January 05, 2016
      Jaap Brasser
      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
      
      Sorry for bothering you again. Thanks!
  • Minmizing the list
    4 Posts | Last post August 26, 2016
    • Is there a way or change in the command itself so that when I receive the list of programs it won't be so long? For example, I noticed that you will see duplicates for past update with certain programs. Can I parse this so that similar programs like that will only appear once to make looking at my list easier?
    • You can filter the output however you would like. But 'similar names' is a bit vague. Can you give an example of how the names are similar then I could give you an example of how to filter out the duplicates.
      
      Regards,
      
      Jaap Brasser
    • Absolutely, For instance I am seeing "Microsoft .Net Framework" and "Microsoft Visual C++ 2012" With many versions of their updates. I'm assuming there is a way to filter them out like you said so I would love to know how to do that. However, if there is anyway to minimize these so I could only see one copy to at least visually show that it is there that would be much more beneficial. Thanks!
    • Hello FWK890,
      
      I have taken a look at your issue and I have introduced two new parameters to deal with the issue. I have introduced two new parameters:
          -ExcludeSimilar
          -SimilarWord
      
      So if you execute the script as follows:
      
      Get-RemoteProgram -ExcludeSimilar -SimilarWord 3
      
      This will filter out similar program names, it filters on the first 3 words in a program name. If a program consists of three or less words it is always included. For example if you Visual Studio 2015 installed it will list all the components individually by default, using -ExcludeSimilar will display one entry of Visual Studio 2015.
  • Unable to run
    2 Posts | Last post July 26, 2016
    • hello Jaap,
      
      I'm very new to this scripting world.
      When i'm trying to run the script as:
      
      Get-RemoteProgram -ComputerName "Laptop-009"
      
      i got the same error as this post by Joel below. Our computer name has a - in it so i guest i have to user "" for it. not sure if its correct.
      
      Would you please help me figure out how to get this to work as your suggestion below to turn on the RemoteRegistry however i do not know how to do it.
      
      Thanks,
      
      "Joel Calvo
      I'm nearly 100% confident that this script only works if the Remote Registry Service is set to Automatic, or Manual on the target computers. If the service is set to disabled, the output of this script will yield the following error: "Exception calling "OpenRemoteBaseKey" with "2" argument(s): "The network path was not found."
      
      Can you please confirm with me the above information? If the above information is correct, can you please help me determine the best way to integrate the ability to turn on or off the Remote Registry Service on all target computers? I'm using Get-Content CMDLET pathed to a text file containing a list of target machines.
      
      Thanks!
      
      Written April 24, 2016
      Jaap Brasser
      That is correct, the script remotely queries the registry for this information. As for remotely activating the service it really depends how locked down your systems are. Initially I would recommend using the WMI/CIM cmdlets for this purpose:
      
      $Service = Get-WmiObject -Query 'Select * FROM Win32_Service WHERE Name="RemoteRegistry"'
      $Service.ChangeStartMode('Automatic')
      $Service.Start()
      
      Let me know if that works for you."
    • Hello TommyNG,
      
      It almost never hurts to wrap your parameter arguments in quotation marks, but in this case it is not necessary. What kind of environment are you working in, if you are in a domain based environment you could create a group policy that enables remote registry on all systems within your domain.
      
      Alternatively you could run the code in my response to Joel. If you want to run it against a remote system you could include the -ComputerName parameter as such:
      
      $Service = Get-WmiObject -Query 'Select * FROM Win32_Service WHERE Name="RemoteRegistry"' -ComputerName server01
      $Service.ChangeStartMode('Automatic')
      $Service.Start()
      
  • Store values in database?
    2 Posts | Last post July 26, 2016
    • Hello,
      
      Is it possible to use this script to store values in a database? For example, if I wanted to get a list of all the applications on all of my domain computers and then run queries against them?
    • Absolutely, there are many tools available to interact with SQL databases, have a look at DBATools:
      https://github.com/ctrlbold/dbatools
      
      My advice would be to query and export to csv and then to import the csv into a SQL database to make it avaialble that way.
  • Changing order of displayed properties
    2 Posts | Last post May 05, 2016
    • I cannot seem to find a way to modify the order that the returned properties are displayed.  
      
      I'm exporting the output to a .csv file, and want the first column to be the ComputerName.  I feel like an idiot asking this, but can you please point me in the right direction? TIA
    • This is something that can be done using the Select-Object cmdlet, for example if you would like to display the computername first you could do something along these lines:
      
      Get-RemoteProgram | Select-Object -Property ComputerName,ProgramName
      
      And I would go as far as calling you an idiot, you are learning and not afraid to ask so at least you learned something today :) If you would like to know more about PowerShell and a large selection of resources to learn more about PowerShell head on over here:
      http://www.jaapbrasser.com/how-to-learn-powershell
  • Basic Use
    4 Posts | Last post April 24, 2016
    • Jaap,
      
      I'm a pretty big powershell noob, do you have a quick tutorial on how I can exceute this one one PC on my network. I'm familiar with basics get-commands but this is kinda verbose.
      
      Thanks,
      
      Kyle
    • Kyle,
      
      Follow the instructions in his description.
      
      1) Open a PowerShell window
      
      2) Use the CD command to Change Directory of PowerShell session to the directory where the Get-RemoteProgram.ps1 file resides. For example, if the .ps1 file resides in C:\Scripts, then run CD C:\Scripts
      
      3) Run the following command next:
      
      Get-RemoteProgram -ComputerName HOSTNAME
      
      Where it says HOSTNAME, you'd replace that with the target machine hostname.
    • Joel,
      
      Thanks, I was able to execute the command without error, but after it completed there was no output in my powershell session. Does the script save a log file somewhere? I've searched through it and can't find anything in the script that specifies anything of the sort.
    • I think in the instructions by Joel Calvo were quite accurate, thanks for that Joel. One step was missing however, so for step 3 could you execute this:
      
      .\Get-RemoteProgram;Get-RemoteProgram -ComputerName HOSTNAME
      
      Let me know if that works better.
      
      
      Regards,
      
      Jaap Brasser
  • Question regarding this script+Remote Registry Service
    2 Posts | Last post April 24, 2016
    • I'm nearly 100% confident that this script only works if the Remote Registry Service is set to Automatic, or Manual on the target computers. If the service is set to disabled, the output of this script will yield the following error: "Exception calling "OpenRemoteBaseKey" with "2" argument(s): "The network path was not found."
      
      Can you please confirm with me the above information? If the above information is correct, can you please help me determine the best way to integrate the ability to turn on or off the Remote Registry Service on all target computers? I'm using Get-Content CMDLET pathed to a text file containing a list of target machines.
      
      Thanks!
    • That is correct, the script remotely queries the registry for this information. As for remotely activating the service it really depends how locked down your systems are. Initially I would recommend using the WMI/CIM cmdlets for this purpose:
      
      $Service = Get-WmiObject -Query 'Select * FROM Win32_Service WHERE Name="RemoteRegistry"'
      $Service.ChangeStartMode('Automatic')
      $Service.Start()
      
      Let me know if that works for you.
      
31 - 40 of 73 Items