How To Find If A Software Installed on Any Remote Computers

1

Obviously, the easiest way to find if a particular software is installed on any computers on a network is to use PowerShell. Let’s go through some of the processes and the ways to speed up the process.

One remote computer

To get a full list of installed program on a remote computer,

Get-WmiObject Win32_Product -ComputerName $computer

But since Get-WmiObject is no longer supported in PowerShell 7, let’s use Get-CimInstance instead since it’s part of the .Net core.

Get-CimInstance Win32_Product -ComputerName $computer

To find a specific program, you can either filter by the IdentifyingNumber

Get-CimInstance Win32_Product -ComputerName $computer | Where-Object {$_.IdentifyingNumber -eq $number}

Or by the Vendor name if there are different versions of the software you want to find.

Get-CimInstance Win32_Product -ComputerName $computer | Where-Object {$_.Vendor -contains $vendor}

Multiple remote computers

Now, how about finding one specific software from multiple remote computers?

If you have a list of computer names in a text file, you can read the file through. Or, easier, just search through a specific IP range.

The catch of searching through an IP is that Get-CimInstance doesn’t take IP directly. You will need to convert them to a host name first. But it’s no big deal to PowerShell, a simple conversion would just do fine.

$computer = ([system.net.dns]::GetHostByAddress($ip).hostname

Put together, using Adobe as an example.

$vendor = "Adobe Systems Incorporated"
$iprange = 100...250
$iprange | ForEach-Object {
  $ip = "192.168.1.$_"
  if (Test-Connection $ip -count 1 -Quiet) {
    $computer = ([system.net.dns]::GetHostByAddress($ip).hostname
    $status = Get-CimInstance Win32_Product -ComputerName $computer | 
                Where-Object {$_.Vendor -contains $vendor}
            if ($status)    {
                $computer + " - " + $ip
                $status
            }
  }
}

The code pings the target device first and will only proceed if it gets the response. It works relatively well, except,

It takes so long

Now let me introduce one of the nice features in PowerShell 7.

ForEach-Object -Parallel -ThrottleLimit

It lets you run the script block in parallel, with the ThrottleLimit limiting the number of script blocks to run at the same time. So,

$vendor = "Adobe Systems Incorporated"
$iprange = 100...250
$iprange | ForEach-Object ThrottleLimit 15 -Parallel  {
  $ip = "192.168.1.$_"
  if (Test-Connection $ip -count 1 -Quiet) {
    $computer = ([system.net.dns]::GetHostByAddress($ip).hostname
    $status = Get-CimInstance Win32_Product -ComputerName $computer | 
                Where-Object {$_.Vendor -contains $vendor}
            if ($status)    {
                $computer + " - " + $ip
                $status
            }
  }
}

Now, I can finish the process easily in minutes, instead of 30 minutes or more.

What can I do after I gathered this information? Well, you can uninstall it if you want to.

1 COMMENT

  1. Hi
    script looks good but missing an output, for this type of task, output is kind of important. I have been struggling with output the result. please help. thanks.

LEAVE A REPLY

Please enter your comment!
Please enter your name here