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

Over the weekend I have taken a look at the request and current functionality of my Get-RemoteProgram script. A script that gathers the installed programs installed on the local or remote systems by querying the registry and displaying the results to the console as PowerShell objects.

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

Three new improvements have been implemented to the script:

  • Correctly searches the Wow6432Node for 32 bit applications on 64 bit systems
  • Added a new parameter -Property to specify additional properties to be loaded from the registry
  • Added support for the pipeline to be used to supply the function with computer names

The new parameter -Property is the biggest change to this script, this for example allows direct un-installation based on the output of Get-RemoteProgram, for example:

Get-RemoteProgram -Property UninstallString |
Where-Object {$_.ProgramName -match 'java'} | ForEach-Object {
    cmd /c $_.uninstallstring
}

Here are some additional examples of how the script can be used:

.EXAMPLE
Get-RemoteProgram

Description:
Will generate a list of installed programs on local machine

.EXAMPLE
Get-RemoteProgram -ComputerName server01,server02

Description:
Will generate a list of installed programs on server01 and server02

.EXAMPLE
Get-RemoteProgram -ComputerName Server01 -Property DisplayVersion,VersionMajor

Description:
Will gather the list of programs from Server01 and attempts to retrieve the displayversion and versionmajor subkeys from the registry for each installed program

.EXAMPLE
'server01','server02' | Get-RemoteProgram -Property Uninstallstring

Description
Will retrieve the installed programs on server01/02 that are passed on to the function through the pipeline and also retrieves the uninstall string for each program
Share

26 thoughts on “Update to Get-RemoteProgram – Get list of installed programs on remote or local computer

  1. lumine99

    Hey Jaap, thanks for the code, I’ve just found your code. it works awesome locally.. However when I specified the computername(trying to get it remote), your code still produce the programs in my local pc. Do you have any idea why this is happening??
    I’ve run your code with admin rights and disabled firewall on the remote pc.

    Reply
    1. Jaap Brasser Post author

      That obviously should not happen, can you show me the exact code that you are using to I can see is causing this behavior? Also which version of the script are you using when you are running into this issue? The version of the script can be viewed by typing Get-Help Get-RemoteProgram.

      Reply
  2. lumine99

    the code I’m using is Get-program -computername Fujitsu
    I’m using your most recent version(the one in this thread) and Version 1.0

    wow… I just re try running your code again and it gave me this result:

    Exception calling “OpenRemoteBaseKey” with “2” argument(s): “The network path was not found.

    At F:\Kuliah\Ide TA\TAku\Coba\Get-RemoteProgram – OLD.ps1:40 char:9
    + $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.W …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : IOException

    You cannot call a method on a null-valued expression.
    At F:\Kuliah\Ide TA\TAku\Coba\Get-RemoteProgram – OLD.ps1:41 char:9
    + $RegUninstall = $RegBase.OpenSubKey(‘SOFTWARE\Microsoft\Windows\CurrentV …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    You cannot call a method on a null-valued expression.
    At F:\Kuliah\Ide TA\TAku\Coba\Get-RemoteProgram – OLD.ps1:42 char:9
    + $RegUninstall.GetSubKeyNames() |
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Reply
    1. lumine99

      I forgot to add that both of the new and old version pops out the same result. Running it locally still works fine though.

      Reply
      1. Jaap Brasser Post author

        The problem here is that you can’t seem to be able to connect to the remote system, it appears that this is a network connectivity issue. What are the results if you attempt to execute one of the following against the same remote system:

        Test-Connection -ComputerName Fujitsu
        Get-Process -ComputerName Fujitsu
        Get-WmiObject -Class Win32_Bios -ComputerName Fujitsu

        Reply
        1. lumine99

          test connection worked well.. though the other two didn\’t> Get-RemoteProgram -ComputerName Fujitsu-p8010Exception calling \”OpenRemoteBaseKey\” with \”2\” argument(s): \”The network path was not found.\”At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:40 char:9+ $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.W …+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : IOException You cannot call a method on a null-valued expression.At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:41 char:9+ $RegUninstall = $RegBase.OpenSubKey(\’SOFTWARE\Microsoft\Windows\CurrentV …+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull You cannot call a method on a null-valued expression.At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:42 char:9+ $RegUninstall.GetSubKeyNames() |+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull==================================================================================> Get-WmiObject -class win32_bios -ComputerName fujistsu-p8010Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)At line:1 char:1+ Get-WmiObject -class win32_bios -ComputerName fujistsu-p8010+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

          Reply
      2. lumine99

        uh oh my prev message didn’t appeared as I’ve intended… feel free to delete it Jaap..

        I’ll re post it to make it easier to read:

        test connection worked well.. though the other two didn’t

        > Get-RemoteProgram -ComputerName Fujitsu-p8010
        Exception calling “OpenRemoteBaseKey” with “2” argument(s): “The network path was not found.

        At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:40 char:9
        + $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.W …
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : IOException

        You cannot call a method on a null-valued expression.
        At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:41 char:9
        + $RegUninstall = $RegBase.OpenSubKey(‘SOFTWARE\Microsoft\Windows\CurrentV …
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

        You cannot call a method on a null-valued expression.
        At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:42 char:9
        + $RegUninstall.GetSubKeyNames() |
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

        ==========================================================================

        > Get-WmiObject -class win32_bios -ComputerName fujistsu-p8010
        Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
        At line:1 char:1
        + Get-WmiObject -class win32_bios -ComputerName fujistsu-p8010
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
        + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

        Reply
  3. Jaap Brasser Post author

    Okay, so the problem is not with the script since the cmdlets in PowerShell are also not working. So there could be a number of reason why this is not working:
    – Firewall on either side
    – RPC Server is unavailable
    – Not using the correct permissions

    Based on the error message you show, it does not appear to be a permissions issue. So which operating systems are you running on both systems, also are the machine domain joined or standalone machines, are there any firewalls running on the systems?

    The following post on the Technet forums gives some suggestions on how to resolve this:
    http://social.technet.microsoft.com/Forums/windowsserver/en-US/f15f233f-097f-42fd-8c05-1aa1d03e4646/getwmiobject-to-remote-computer-fails-with-rpc-server-is-unavailable-and-vice-versa-access?forum=winserverpowershell

    If you are running older versions of Windows that is not up to date with patches, making sure that your system is completely patched might resolve these issues.

    Reply
  4. lumine99

    both are win8, x64 and x86. both are standalone machine(2 laptops). I followed your link, there is this numbered post, number 1 and 2 are default setting. both of my laptops are missing this service “Windows Management Instrumentation Driver Extensions” . manually running all of them yet still no effect.
    as of number 4, I am using avast antivirus. and disabling all shields still yield no success here.
    though right now the error is different from the previous one…

    Exception calling “OpenSubKey” with “1” argument(s): “Requested registry access is not allowed.”
    At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:75 char:17
    + $RegUninstall = $RegBase.OpenSubKey($CurrentReg)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SecurityException

    Exception calling “OpenSubKey” with “1” argument(s): “Requested registry access is not allowed.”
    At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:75 char:17
    + $RegUninstall = $RegBase.OpenSubKey($CurrentReg)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SecurityException

    Reply
  5. Jaap Brasser Post author

    Well, disabling avast has resolved the connectivity issues, now it seems to be a permissions issue. Because you are in a workgroup environment. One method to get this to work is to run this script with an account with administrative privileges on both systems, you can set this up by creating a user account with the same name and the same password on both system and making this user an admin on both systems. Could you create such an account and verify if you still receive the same error you received in your last post.

    Reply
  6. lumine99

    Yes, I still receive the same error as before…

    Exception calling “OpenSubKey” with “1” argument(s): “Requested registry access is not allowed.”
    At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:75 char:17
    + $RegUninstall = $RegBase.OpenSubKey($CurrentReg)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SecurityException

    Exception calling “OpenSubKey” with “1” argument(s): “Requested registry access is not allowed.”
    At F:\Kuliah\Ide TA\TAku\Coba\Used\Get-RemoteProgram.ps1:75 char:17
    + $RegUninstall = $RegBase.OpenSubKey($CurrentReg)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SecurityException

    Reply
  7. Chip Duncan

    New to Powershell. Really like your code. Unsure how to take it to a little deeper level. I want to run something like this (below). I have a CSV list of about 340 servers and want to not have to copy / paste them in (which does work and finishes in about 18 minutes.) I’m trying to build something I can hand off to other people in my shop who have even less Powershell than me.

    This is an example of what I’m trying to do…

    Get-RemoteProgram -ComputerName (Import-Csv C:\SCRIPT\ComputerList.csv)

    Reply
  8. Jaap Brasser Post author

    Hello Chip,

    Thanks, it’s good to hear you find my script useful!

    So the reason Import-Csv does not work, is that the Import-Csv cmdlet will import the entire csv file as an array of objects. The ComputerName parameter either accepts a string or an array of strings containing the computer name. Assuming your csv file has a ComputerName header you could do the following:

    Import-Csv C:\Script\ComputerList.csv | Get-RemoteProgram
    Import-Csv C:\Script\ComputerList.csv | ForEach-Object {Get-RemoteProgram -ComputerName $_.ComputerName}
    Get-RemoteProgram -ComputerName (Import-Csv C:\SCRIPT\ComputerList.csv | Select-Object -ExpandProperty ComputerName)

    You can use whatever you find convenient, although I would recommend using the pipeline as it is easier to read and see what is going on.

    Reply
  9. Tobi

    Hello Jaap, i have one Problem with the Script
    if i load the Script in Powershell ISE it worked fine if i run the Script from CMD it gave no Result. No Output no Error

    start cmd and type the code
    powershell C:\Users\administrator\Downloads\Get-RemoteProgram.ps1 -ComputerName ito-testimage -Property DisplayVersion

    C:\Windows\System32>

    powershell set-executionpolicy unrestricted is set and iam domain administrator

    i hope you can help me

    thx !!

    Reply
    1. Jaap Brasser Post author

      Sure, could you try running it like this, this should work because I first dot source the function in the script and then I call the function:

      powershell -noprofile -command “& {. C:\Users\administrator\Downloads\Get-RemoteProgram.ps1;get-remoteprogram -ComputerName ito-testimage -property displayversion}”

      Reply
  10. Yermek

    Hello Jaap,
    I have a problem with the Script, for some reason a cannot export this report into .CSV file and save it for example on my desk. Can you please provide commands to export this?
    I tried for function, but it’s doesn’t work:
    | Out-File -Filepath “D:\Files\dll.txt”

    Reply
    1. Jaap Brasser Post author

      How about if you pipe the command into the Export-Csv cmdlet:

      Get-RemoteProgram | Export-Csv -Path YourFile.csv -NoTypeInformation

      Reply
  11. Matt

    Hi Jaap,

    Thanks so much for the script. I am having some issues where the script just doesn’t seem to run. I have tried running as domain admin, running as local admin but nothing happens. When i try the Get-RemoteProgram I receive an error stating that this is not recognized as the name of the cmdlet, function, script file etc.. Any Suggestions?

    Reply
    1. Matt

      I was able to get the script running now, that was me being dumb. I am able to get my local PC programs but get a “Network Path was not found” when trying to get a remote PC’s list of programs. I am able to use the “wmic /node:”ComputerName” product get name,version” to get a list from a remote PC but for some reason i cant with your script.

      Reply
      1. Jaap Brasser Post author

        Hey Matt,

        Could you give the full syntax of the command you are executing and the full error message you receive, then I can take a look and see if I can see where the error is coming from.

        Reply
  12. Graeson

    Thank you for making this script available, it is phenomenal! I am brand new to PowerShell and this was clean and easy to follow through. I am curious if one thing might be possible. I am currently using the following command to query a list of computers and then export the results to a csv file:

    Import-Csv C:\holding\Scripts\ComputerList.csv | Get-RemoteProgram | Export-Csv -Path YourFile.csv -NoTypeInformation

    Is there a way to check for / match a specific program name? If not, I can simply sort the csv and pull out the info I need.

    Thank you again!

    Reply
    1. Jaap Brasser Post author

      Absolutely, the Where-Object cmdlet allows you to filter for specific conditions. So if for example you are only interested in programs that contain Microsoft Office as part of their name you could do something along these lines:

      Import-Csv C:\holding\Scripts\ComputerList.csv | Get-RemoteProgram | Where-Object {$_.ProgramName -like 'Microsoft Office*'} | Export-Csv -Path YourFile.csv -NoTypeInformation

      The -Object cmdlets are quite powerful for filtering any collection of objects, have a look the available cmdlets:
      Get-Command -Noun Object
      Get-Help Where-Object -Full

      The PowerShell help is very useful and contains a lot of useful examples, I often use it whenever I am writing code with a cmdlet I am not familiar with.

      Regards,

      Jaap Brasser

      Reply
  13. MReprogle

    I’m a total noob at Powershell, but I keep receiving the following error when attempting to run the script:

    PS Z:\> Get-RemoteProgram -ComputerName “msmith”
    Get-RemoteProgram : The term ‘Get-RemoteProgram’ is not recognized as the name of a cmdlet, function, script file, or
    operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
    again.
    At line:1 char:1
    + Get-RemoteProgram -ComputerName “msmith”
    + ~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (Get-RemoteProgram:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    Is there something that I am totally missing? I feel like it is definitely something that I am doing wrong. Even if I change the path from the z:\ drive to the c:\, I get the same error message..

    Reply
    1. Jaap Brasser Post author

      Hello MReprogle,

      So what you need to do is first load the function in the script, so assuming you are in the folder containing the .ps1 file run the following:

      . .\Get-RemoteProgram.ps1
      Get-RemoteProgram -ComputerName “msmith”

      Let me know how that works for you!

      Regards,

      Jaap Brasser

      Reply

Leave a Reply