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-Packagecmdlet on remote machines by executing it as a part of theInvoke-Commandcmdlet orEnter-PSSessioncmdlet 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 $resultvariable 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-ChildItemcmdlet to query the registry to retrieve a list of all the installed packages (software). - Use the
ForEachloop to iterate over the list of installed packages. - In each iteration:
- Use
Write-Hostthrice to show theDisplayNameof 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.