Lead Image © Andrea De Martin, 123RF.com

Lead Image © Andrea De Martin, 123RF.com

Software inventory with PowerShell

Data Detective

Article from ADMIN 51/2019
PowerShell easily combines different interfaces for querying or reporting data.

PowerShell provides several ways to access the installed software. Because it supports a variety of interfaces, administrators have freedom of choice in data collection. Depending on the operating system and your own objectives, the method can be different. The access methods can also be combined, and the result sets transferred to the output routines. From database-supported inventory to an HTML report sent by email, many options are available.

Since Windows NT, the Windows Management Instrumentation (WMI) class group has offered administrators an interface pool for hardware, software, infrastructure, and directory services. Two classes are of interest if you need an overview of installed software: the Win32_Product system library and the Win32Reg_AddRemovePrograms class. Win32_Product does not require any additional installed components, and it is available on Windows client and server systems. The following command provides an overview of attributes that can be used for a report:

> Get-WmiObject -class Win32_Product | Get-Member -MemberType Properties ;

If you now take advantage of PowerShell's filtering capabilities, you can create a vendor-specific report. The pipeline can deliver all the installed programs for a specific vendor:

> Get-WmiObject -class Win32_Product | Where-Object -FilterScript 
  {$_.vendor -eq "Microsoft Corporation"}
Microsoft System Center Configuration Manager
  (SCCM, also known as ConfigMgr), formerly Systems Management Server (SMS)

The other WMI class useful for software inventory work is not a system library. Win32Reg_AddRemovePrograms is only loaded during the installation of a Systems Management Server (SMS)/System Center Configuration Manager (SCCM) client. A query without an SMS/SCCM client installation leads to the Invalid class error message. If Win32Reg_AddRemovePrograms is available, however, the performance is significantly faster than with the Win32_Product class, which can require some patience on the part of the admin.

Although WMI is characterized by very extensive access capabilities and compatibility with legacy operating systems, it has some serious disadvantages:

  • The interface is MSI-based only; NuGet or other package managers are not considered.
  • It is based on DCOM, a very old technology. Remote queries are possible but require firewall exceptions.
  • Evaluating return values can be problematic because of slow processing speed.

Direct Approach

The registry approach is often more effective for maintaining installed software. The Windows PowerShell registry provider (PSProvider) supplies actions for manipulating registry keys. Entries and values can be retrieved, added, changed, or deleted in PowerShell. PSProvider provides a hierarchical namespace consisting of registry keys and subkeys. Registry entries and values are not components of this hierarchy; instead, they are properties of the individual keys. The registry provider supports all cmdlets that contain the Item or ItemProperty noun, which covers all CRUD (create, read, update, delete) actions.

The installer properties can be found under the HKLM/Software/Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall registry key. The values are stored in a subkey identified by the globally unique identifier (GUID) product code. The Get-ItemProperty cmdlet is very useful for analyzing items in the filesystem or registry. To output the available software, enter:

> Get-ItemProperty 
  "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" | 
  Select-Object display name, display version, publisher, install date | Format-Table -AutoSize

At first, searching the registry seems clumsy and outmoded, but this procedure is surprisingly effective. The entries are available in the database and do not have to be collected again by queries. Remote queries through a .NET class are also possible. To get started with a remote query of the registry, enter:

> Return = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey
  ("$Key", "$ComputerName")

Universal Approach

Microsoft provides a software installation tool for the command line in Windows Management Framework 5 and the included PowerShell 5. The PackageManagement module provides a simple interface that is easy to automate and is already included in Windows 10. Uniform management of the software to be installed, as well as the ability to provision and version the sources, are the objectives of this new concept.

The Advanced Packaging Tool (APT), known from the Unix world, stores its software in repositories, or package sources, from which software is then retrieved with command-line tools like apt-get. For an enterprise solution, flexible handling of the packages themselves (even of different types), the ability to create and update enterprise-specific sources, and effective front-end solutions play a major role. At the moment, you will find many other package formats besides the Windows Installer format, which processes MSI packages. The PackageManagement module is not a new package manager, but a package manager management solution. The cmdlets include the Package noun (Figure 1).

Figure 1: PowerShell PackageManagement module commands.

The Get-Package cmdlet displays all the installed software packages (Figure 2). The source and the repository are initially irrelevant. However, if required, the command's parameters offer interesting query options. The simple approach to standard output is more comprehensive than the approaches shown so far. Package sources and versions can be important criteria when selecting a package for an automated installation with Install-Package.

Figure 2: Outputting the installed software with Get-Package.

PackageManagement does not simply build on the semantics of existing solutions found in NuGet (in the Visual Studio environment) or MyGet; it offers a consistent approach, with its own plugin system, full .NET integration, a WMI provider, and a true PowerShell module. Other cmdlets in the language family,

  • Find-Package, which identifies software from local repositories or online, and
  • Install-Package/Uninstall-Package, which provide software management with version and source selection,

are worth a look, as well.

Creating Reports

The pipeline method is often all it takes to create a report:

> Get-Package -ProviderName msi -AllVersions | 
  Select-Object -Property name, version, source | 
  Export-Csv -NoTypeInformation -Delimiter ";" -Path $StrOutpath;

A report based on access to the registry combined with remote execution of PowerShell statements is shown in Listing 1.

Listing 1

Registry Access Report

01 # The path to a text file with one FQDN computer name on each line.
02 # is stored in the StrComputerNamesList variable
04 Foreach ($StrComputerName in (get-Content StrComputerNamesList))
  { Invoke-Command -ComputerName StrComputerName -ScriptBlock
  { Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\
  Uninstall\*" | Select-Object display name, publisher, install date | 
  ConvertTo-Html | Out-File "$SMBShare\Report.html"; }}

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.