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.
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.