Check computers for installed program in powershell

11.2k Views Asked by At

I want to be able to look for an installed program in powershell and output to a file the results. So far, I have something that will list the install programs, and select the string that has the name of the program, but I am not sure how to specify a text file for it to use for the list of systems, and a way to make it output cleanly.

Get-WmiObject -Class Win32_Product -cn $computernamehere | Select-Object -Property Name | Sort-Object Name | Select-String Vmware | Out-File C:\Users\ajstepanik\Desktop\installed_programs.txt

I would like it to output in a fashion like:

COMPUTER1 - VMware Horizon View Client
COMPUTER2 - VMware Horizon View Client
COMPUTER3 - VMware Horizon View Client

Currently it outputs:

@{Name=VMware Horizon View Client}
@{Name=VMware Horizon View Client}
@{Name=VMware Horizon View Client}
2

There are 2 best solutions below

7
On BEST ANSWER

In your case I recant my previous statement about -ExpandProperty. I am still right in that it will return just a string array instead of the object property. However I think that you will have more options if you leave it as an object and just add the property "Computer" which you are looking for. That was we can just have it as a nice CSV! I am going to assume there is some loop structure here that you have not shown.

$list = Get-Content C:\Users\ajstepanik\Desktop\computers.txt
$list | ForEach-Object{
    $computer = $_
    Get-WmiObject -Class Win32_Product -ComputerName $computer | 
            Select-Object -Property Name | 
            Sort-Object Name | 
            Where-Object{$_.Name -match "Citrix"} | 
            Add-Member -MemberType NoteProperty -Name "Computer" -Value $computer -passthru
} | Export-Csv -NoTypeINformation -Path C:\temp\path.csv

Changed the select-string to a WherenMatch since i kept the object. Used Add-Member to add a property for Computer. Now we can use Export-CSV

Forgot about foreach($x in $y) doesnt work with output the way the other foreach does.

1
On

Let C:\ComputerList.txt be a list of computers with one computer name on each line like:

COMPUTER1
COMPUTER2
COMPUTER3
COMPUTER4

So, here's how I would do it:

$ComputerListFile = 'C:\ComputerList.txt';
$OutputFile = 'C:\VMWareSoftwareReport.csv';

#Variable for the report with header
$Report = @();
$Report += '"ComputerName","SoftwareName","SoftwareVersion"';

#Get the list of computers
$ComputerList = Get-Content $ComputerListFile;

$ComputerList | ForEach-Object {
    $ComputerName = $_;
    #Ping the target to see if it's there
    If ((Get-WmiObject Win32_PingStatus -Filter "Address='$ComputerName' AND Timeout=1000").StatusCode -eq 0) {
        #Get the list of software
        $vmWareSoftware = Get-WmiObject -Query "SELECT Name, Version FROM Win32_Product WHERE Name LIKE '%vmWare%'" -ComputerName $ComputerName | Sort-Object -Property Name;
        $vmWareSoftware | ForEach-Object {
            #Format the results, escape any double quotes, and add them to the report
            $SoftwareName = $_.Name.Replace('"','""');
            $SoftwareVersion = $_.Version.Replace('"','""');
            $Report += '"{0}","{1}","{2}"' -f $ComputerName, $SoftwareName, $SoftwareVersion;
        }
    }
}

#Write the report file, overwriting if needed
Set-Content -Path $OutputFile -Value $Report -Force;

You might want to use Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* as @expirat001 mentions, but Get-ItemProperty can't target remote computers. It also may not be a complete listing. For that matter, Win32_Product may not be complete, either. There's no comprehensive way to find all installed software in Windows.

Note also that Out-File by default will overwrite, not append. You have to specify the -Append switch, or you'd just get the one computer in the file.