There are situations when you need to check whether you or your users have certain software installed and what version it is. You may want to verify that the software is up to date or that your GPO-deployed software was installed for a specific user. I’ll show you several methods you can use to verify this using PowerShell.
Fast navigation:
Check what is installed on your computer
To check what software is installed, you can use at any time programs and functions in your control panel or search all hard drive partitions for a specific app. You can even try locating an app in the Start menu to launch it and manually look for its version number. The problem with these methods, however, is that they’re about as far from “quick and automatic” as they can get. Checking installed software versions using PowerShell allows you to collect data you need much faster.
Get the list of installed software with Get-WmiObject
The first method is as simple as pasting a simple query:
Get-WmiObject -Class Win32_Product
You can also easily filter the data to find specific applications from a single vendor along with their versions, for example:
Get-WmiObject -Class Win32_Product | where vendor -eq CodeTwo | select Name, Version
Although this method is very simple, it has one major drawback – it takes quite a long time to return the results.
Query registry for installed software
Another method to get a list of installed software is to query the registry. The following short script returns the list of applications along with their versions:
$InstalledSoftware = Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall" foreach($obj in $InstalledSoftware){write-host $obj.GetValue('DisplayName') -NoNewline; write-host " - " -NoNewline; write-host $obj.GetValue('DisplayVersion')}
Now take a quick look at those HKLM Item in bold above. This means that the list of software returned by the script is all software installed on the LM – the local machine. However, applications can also be installed per user. To return a list of the currently logged-in user’s applications, change HKLM to HKCU
(CU stands for “current user”):
$InstalledSoftware = Get-ChildItem "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall"
foreach($obj in $InstalledSoftware){write-host $obj.GetValue('DisplayName') -NoNewline; write-host " - " -NoNewline; write-host $obj.GetValue('DisplayVersion')}
Retrieving the list of recently installed software from the event log
If you just want to check the recently installed software, you can use the following cmdlet to search the event log.
Get-WinEvent -ProviderName msiinstaller | where id -eq 1033 | select timecreated,message | FL *
This method of finding installed software is most reliable for the most recently added items, since event logs are set by default to overwrite the oldest records (circular logging).
Learn more about using PowerShell to examine Windows event logs and filter results
Get a list of installed software remotely
Any of the above methods can also be used to check software installed on other computers on the same network. If you are creating a list of all the computer names on your network, you can use the following methods within a foreach loop to return results from more than a single remote PC.
$pcname in each script is the name of the remote computer on which you want to get a list of installed software and their versions.
Get the list of installed software using the remote Get-WmiObject command
Again, the following cmdlet is the simplest of the bunch, but may take some time to complete:
Get-WmiObject Win32_Product -ComputerName $pcname | select Name,Version
where $pcname is the name of the computer you want to query.
Check the installed software with a remote registry query
Remote registry queries are a bit more complicated and require the remote registry service to be running. An example query is as follows:
[email protected]() $InstalledSoftwareKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" $InstalledSoftware=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$pcname) $RegistryKey=$InstalledSoftware.OpenSubKey($InstalledSoftwareKey) $SubKeys=$RegistryKey.GetSubKeyNames() Foreach ($key in $SubKeys){ $thisKey=$InstalledSoftwareKey+"\\"+$key $thisSubKey=$InstalledSoftware.OpenSubKey($thisKey) $obj = New-Object PSObject $obj | Add-Member -MemberType NoteProperty -Name "ComputerName" -Value $pcname $obj | Add-Member -MemberType NoteProperty -Name "DisplayName" -Value $($thisSubKey.GetValue("DisplayName")) $obj | Add-Member -MemberType NoteProperty -Name "DisplayVersion" -Value $($thisSubKey.GetValue("DisplayVersion")) $list += $obj } $list | where { $_.DisplayName } | select ComputerName, DisplayName, DisplayVersion | FT
Check the list of recently installed software remotely from the event log
To remotely inspect a user’s event log, a single attribute (-ComputerName) must be added to the previously used cmdlet:
Get-WinEvent -ComputerName $pcname -ProviderName msiinstaller | where id -eq 1033 | select timecreated,message | FL *
Check if any software provided by GPO has been applied successfully
If you have applied a specific software version via GPO, you can easily check whether this GPO has been successfully applied to a user or not. All you need is the GPResult tool and the target computer and user names:
gpresult /s "PCNAME" /USER "Username" /h "Target location of the HTML report"
Then look for your GPO name and see if it’s listed under it Applied Group Policy Objects or Denied GPOs. The sample GPO below is in the Applied Group Policy Objects Group.