Table of Contents
Using Get-Package
with Select-Object
Cmdlet
Use Get-Package
with the Select-Object
cmdlet to check if the specified software is installed.
1 2 3 4 |
$software = "Java(TM) SE Development Kit 18.0.2.1 (64-bit)" Get-Package | Where-Object { $_.Name -eq $software } | Select-Object Name, Version |
1 2 3 |
Java(TM) SE Development Kit 18.0.2.1 (64-bit) |
First, we declared and initialized a variable called $software
having a software’s complete name that we wanted to check.
Next, we used the Get-Package
cmdlet to retrieve a list of all packages installed on our local computer; all these packages were piped to the Where-Object cmdlet which checked whether the Name
property is equal to the value of $software
variable; if it is then, piped the result to the Select-Object
cmdlet, which selected the specified $software
from them and returned them; otherwise, didn’t display anything.
We can also run the
Get-Package
cmdlet on remote machines by executing it as a part of theInvoke-Command
cmdlet orEnter-PSSession
cmdlet or script.
We can also check all versions of a particular software provided by a provider. We use the Get-Package
cmdlet with -ProviderName
and -AllVersions
parameters.
1 2 3 |
Get-Package -Name "Python*"-ProviderName msi -AllVersions |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
Name Version Source ProviderName ---- ------- ------ ------------ Python Launcher 3.11.7966.0 msi Python 3.11.0 Standard Libr... 3.11.150.0 msi Python 3.11.0 Core Interpre... 3.11.150.0 msi Python 3.10.6 Add to Path (... 3.10.6150.0 msi Python 3.11.0 Utility Scrip... 3.11.150.0 msi Python 3.10.6 Standard Libr... 3.10.6150.0 msi Python 3.10.6 Test Suite (6... 3.10.6150.0 msi Python 3.11.0 Tcl/Tk Suppor... 3.11.150.0 msi Python 3.10.6 Executables (... 3.10.6150.0 msi Python 3.10.6 Utility Scrip... 3.10.6150.0 msi Python 3.11.0 Documentation... 3.11.150.0 msi Python 3.10.6 Documentation... 3.10.6150.0 msi Python 3.11.0 Test Suite (6... 3.11.150.0 msi Python 3.10.6 Tcl/Tk Suppor... 3.10.6150.0 msi Python 3.10.6 Core Interpre... 3.10.6150.0 msi Python 3.11.0 pip Bootstrap... 3.11.150.0 msi Python 3.10.6 Development L... 3.10.6150.0 msi Python 3.11.0 Add to Path (... 3.11.150.0 msi Python 3.11.0 Executables (... 3.11.150.0 msi Python 3.10.6 pip Bootstrap... 3.10.6150.0 msi Python 3.11.0 Development L... 3.11.150.0 msi |
We have already learned about Get-Package; here, we used this cmdlet with the -ProviderName
parameter to mention the provider’s name, which was msi
in the above example. Next, we used the -Name
parameter to mention the software’s name; however, the wildcard operator represented with *
was used to grab all the software starting with the word Python
.
Next, we used the -AllVersions
parameter to retrieve all software versions installed on the local machine. By default, the Get-Package
cmdlet returns the latest available version. To list a particular software version, we use -RequiredVersion
followed by the version number. See the following example for a clear understanding.
1 2 3 |
Get-Package -Name "Python*"-ProviderName msi -RequiredVersion 3.11.150.0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Name Version Source ProviderName ---- ------- ------ ------------ Python 3.11.0 Standard Libr... 3.11.150.0 msi Python 3.11.0 Core Interpre... 3.11.150.0 msi Python 3.11.0 Utility Scrip... 3.11.150.0 msi Python 3.11.0 Tcl/Tk Suppor... 3.11.150.0 msi Python 3.11.0 Documentation... 3.11.150.0 msi Python 3.11.0 Test Suite (6... 3.11.150.0 msi Python 3.11.0 pip Bootstrap... 3.11.150.0 msi Python 3.11.0 Add to Path (... 3.11.150.0 msi Python 3.11.0 Executables (... 3.11.150.0 msi Python 3.11.0 Development L... 3.11.150.0 msi |
If you want to know which packages (software) are installed on your local computer, we just run the Get-Package
cmdlet as demonstrated below. It will display the software’s Name
, Version
, Source
, and ProviderName
; see the following output.
1 2 3 |
Get-Package |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Name Version Source ProviderName ---- ------- ------ ------------ Greenshot 1.2.10.6 1.2.10.6 Programs Office 16 Click-to-Run Exte... 16.0.16130.20218 msi Office 16 Click-to-Run Lice... 16.0.16130.20218 msi Microsoft Update Health Tools 3.70.0.0 msi Apache NetBeans IDE 15 15 Programs Node.js 18.12.1 msi Microsoft Visual C++ 2019 X... 14.28.29325 msi Microsoft Visual C++ 2019 X... 14.28.29325 msi Java(TM) SE Development Kit... 18.0.2.1 C:\Program Files\Java\jdk-18.... msi ... ... ... ... ... ... ... ... ... ... ... ... |
There can be a possibility where you have to find out the installation location of the specified software; in that case, we use the Get-Package
with the Select-Object
cmdlet as follows.
1 2 3 4 |
$software = "Java(TM) SE Development Kit 18.0.2.1 (64-bit)" Get-Package -Name $software | Select-Object -ExpandProperty Source |
1 2 3 |
C:\Program Files\Java\jdk-18.0.2.1\ |
We have already learned about Get-Package
and Select-Object
; the new thing is the -ExpandProperty
parameter which we used to specify the property we wanted to select. So, for example, in the above code fence, we selected the source
property to know the installation location of the specified $software
.
Using Get-WmiObject
with Select-Object
Cmdlet
Use Get-WmiObject
with the Select-Object
cmdlet to check if the specified software is installed.
1 2 3 4 |
$software = "Java(TM) SE Development Kit 18.0.2.1 (64-bit)" Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -eq $software } | Select-Object $software |
1 2 3 |
Java(TM) SE Development Kit 18.0.2.1 (64-bit) |
This example is similar to the first example in the previous section, but we used the Get-WmiObject
cmdlet with the -Class
parameter for the above code snippet. This cmdlet retrieved all the instances of the WMI (Windows Management Instrumentation) class or information about the available classes.
Using this cmdlet as Get-WmiObject -Class Win32_Product
returned a list of all the installed software on the Windows system using WMI. We can run this command on any Windows system with PowerShell installed and get details about all the installed packages, including the software’s name, vendor, version, and other important information.
Remember, using Get-WmiObject
can be slow and resource-intensive, particularly when we have a system with many installed software/packages. Why is it slow? It is because it has to query the WMI database for every installed software. Further, few antivirus software may identify it as a malicious command, as the malware frequently uses it to collect information about the installed packages on a particular system. You must be careful using this and only on trusted systems.
Now, let’s modify the above code as demonstrated below.
1 2 3 4 5 6 7 8 9 10 |
$software = "Java(TM) SE Development Kit 18.0.2.1 (64-bit)" $result = Get-WmiObject -Query "SELECT * FROM Win32_Product WHERE Name = '$software'" if ($result -ne $null){ Write-Host "'$software' is installed." } else{ Write-Host "'$software' is not installed." } |
1 2 3 |
'Java(TM) SE Development Kit 18.0.2.1 (64-bit)' is installed. |
Here, we initialize the $result
variable with the value returned by the Get-WmiObject
command. Next, we used the if
statement with the -ne
operator to check if the $result
is not equal to $null
; if it is not, we used Write-Host
to display a customized message informing the specified software is installed; otherwise, the else
block will be executed.
Now we know the Get-WmiObject
cmdlet, why we use it, and what it returns. Let’s use another code example but with function this time.
1 2 3 4 5 6 7 |
function Check_Software_Installed( $software ) { $wmi_check = (Get-WmiObject -Query "SELECT * FROM Win32_Product Where Name='$software'") return $wmi_check; } Check_Software_Installed("Java(TM) SE Development Kit 18.0.2.1 (64-bit)") |
1 2 3 4 5 6 7 |
IdentifyingNumber : {F3A2A837-F83B-5732-97F2-309BE0F51E0C} Name : Java(TM) SE Development Kit 18.0.2.1 (64-bit) Vendor : Oracle Corporation Version : 18.0.2.1 Caption : Java(TM) SE Development Kit 18.0.2.1 (64-bit) |
We got Vendor
, Version
, Caption
, Name
, and IdentifyingNumber
because we used *
in SQL SELECT
command. So we can get the same information for all the installed packages as follows.
1 2 3 |
Get-WmiObject -Class Win32_Product |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
IdentifyingNumber : {89581302-705F-42C5-99B0-E368A845DAD5} Name : Microsoft Update Health Tools Vendor : Microsoft Corporation Version : 3.70.0.0 Caption : Microsoft Update Health Tools IdentifyingNumber : {7B9BAA62-C960-4309-A639-28FC9877FF68} Name : Node.js Vendor : Node.js Foundation Version : 18.12.1 Caption : Node.js IdentifyingNumber : {F3A2A837-F83B-5732-97F2-309BE0F51E0C} Name : Java(TM) SE Development Kit 18.0.2.1 (64-bit) Vendor : Oracle Corporation Version : 18.0.2.1 Caption : Java(TM) SE Development Kit 18.0.2.1 (64-bit) ... ... ... ... ... ... |
Using Get-ChildItem
Cmdlet
To check all the installed software in PowerShell:
- Use the
Get-ChildItem
cmdlet to query the registry to retrieve a list of all the installed packages (software). - Use the
ForEach
loop to iterate over the list of installed packages. - In each iteration:
- Use
Write-Host
thrice to show theDisplayName
of the software, a separator, and theDisplayVersion
.
- Use
1 2 3 4 5 6 7 8 |
$installedSoftware = Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall" foreach($object in $installedSoftware){ Write-Host $object.GetValue('DisplayName') -NoNewline; Write-Host " - " -NoNewline; Write-Host $object.GetValue('DisplayVersion') } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
Greenshot 1.2.10.6 - 1.2.10.6 Apache NetBeans IDE 15 - 15 Notepad++ (64-bit x64) - 8.4.4 Microsoft 365 Apps for enterprise - en-us - 16.0.16130.20218 Microsoft OneDrive - 23.038.0219.0001 R for Windows 4.2.1 - 4.2.1 WinRAR 6.11 (64-bit) - 6.11.0 XAMPP - 8.1.6-0 Python 3.10.6 Development Libraries (64-bit) - 3.10.6150.0 Python 3.11.0 pip Bootstrap (64-bit) - 3.11.150.0 Python 3.10.6 Test Suite (64-bit) - 3.10.6150.0 Python 3.10.6 Utility Scripts (64-bit) - 3.10.6150.0 Python 3.11.0 Core Interpreter (64-bit) - 3.11.150.0 Microsoft Visual C++ 2019 X64 Additional Runtime - 14.28.29325 - 14.28.29325 Typora 1.4 - 1.4.3 Python 3.10.6 pip Bootstrap (64-bit) - 3.10.6150.0 Python 3.10.6 Documentation (64-bit) - 3.10.6150.0 Python 3.10.6 Add to Path (64-bit) - 3.10.6150.0 Oracle VM VirtualBox 7.0.6 - 7.0.6 Windows PC Health Check - 3.6.2204.08001 Python 3.11.0 Tcl/Tk Support (64-bit) - 3.11.150.0 Python 3.11.0 Development Libraries (64-bit) - 3.11.150.0 Python 3.10.6 Executables (64-bit) - 3.10.6150.0 Node.js - 18.12.1 Microsoft Visual C++ 2019 X64 Minimum Runtime - 14.28.29325 - 14.28.29325 Update for Windows 10 for x64-based Systems (KB5001716) - 4.91.0.0 Microsoft Update Health Tools - 3.70.0.0 Office 16 Click-to-Run Licensing Component - 16.0.16130.20218 Office 16 Click-to-Run Extensibility Component - 16.0.16130.20218 Python 3.10.6 Tcl/Tk Support (64-bit) - 3.10.6150.0 Python 3.11.0 Add to Path (64-bit) - 3.11.150.0 Python 3.11.0 Executables (64-bit) - 3.11.150.0 ScreenToGif - 2.37.1 Python 3.11.0 Utility Scripts (64-bit) - 3.11.150.0 Python 3.10.6 Standard Library (64-bit) - 3.10.6150.0 Python 3.10.6 Core Interpreter (64-bit) - 3.10.6150.0 Python 3.11.0 Standard Library (64-bit) - 3.11.150.0 Python 3.11.0 Documentation (64-bit) - 3.11.150.0 Python 3.11.0 Test Suite (64-bit) - 3.11.150.0 Java(TM) SE Development Kit 18.0.2.1 (64-bit) - 18.0.2.1 |
We used Get-ChildItem to query the registry and get all the installed software on the local machine. We stored this list in the $installedSoftware
variable, which we used with the ForEach
loop. The loop iterated over the $installedSoftware
, and we used the Write-Host
cmdlet thrice for every element in the list.
First, Write-Host
was used to print the DisplayName
of the current software retrieved using the GetValue()
method. The second Write-Host
cmdlet was used to print a separator; we used -
; you can use any of your choices. Third, Write-Host
printed the DisplayVersion
of the current software, which we got using using GetValue()
method. Finally, the -NoNewLine
was used not to insert a line break.
The above code lists all the software installed on our local machine, but the applications can be installed per user too. So, to get a list of software for a currently logged-in user, we have to change the HKLM
to HKCU
as demonstrated below. So, here, LM
means Local Machine while CU
means Current User.
1 2 3 4 5 6 7 8 |
$installedSoftware = Get-ChildItem "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall" foreach($object in $installedSoftware){ Write-Host $object.GetValue('DisplayName') -NoNewline; Write-Host " - " -NoNewline; Write-Host $object.GetValue('DisplayVersion') } |
1 2 3 4 5 6 7 8 |
Microsoft Teams - 1.5.00.21668 Zoom - 5.13.3 (11494) Python 3.10.6 (64-bit) - 3.10.6150.0 Telegram Desktop - 4.4 Microsoft Visual Studio Code (User) - 1.74.3 Python 3.11.0 (64-bit) - 3.11.150.0 |
To get information in tabular form, we can use the following solution.
1 2 3 4 5 |
Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize |
1 2 3 4 5 6 7 8 9 10 11 |
DisplayName DisplayVersion Publisher InstallDate ----------- -------------- --------- ----------- Google Chrome 111.0.5563.64 Google LLC 20230310 Microsoft Edge 110.0.1587.63 Microsoft Corporation 20230304 Microsoft Edge WebView2 Runtime 110.0.1587.63 Microsoft Corporation 20230306 Python Launcher 3.11.7966.0 Python Software Foundation 20221108 Teams Machine-Wide Installer 1.5.0.8070 Microsoft Corporation 20220916 ... ... ... ... ... ... ... ... |
We used Get-ItemProperty cmdlet to retrieve the DisplayName
, DisplayVersion
, Publisher
, InstallDate
properties of the selected objects. In contrast Format-Table
cmdlet was used to display the received data in a tabular format.
That’s all about how to check if Software is installed.