Software inventory with PowerShell
Data Detective
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).
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
.
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, andInstall-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 03 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
(incl. VAT)