Build a Reusable Windows Software Inventory Script from Registry Evidence
Inventory machine-wide installed applications from 64-bit and 32-bit uninstall registry views, normalize duplicate records, and document what registry inventory does not cover.
Expected Outcome
A PowerShell script returns normalized application records without invoking Win32_Product, reconciles both machine-wide uninstall registry views, and explicitly reports inventory limitations for per-user/MSIX/AppX software.
Assumptions
Windows test endpoint with PowerShell
Read access to HKLM uninstall registry locations
A short list of known installed applications for reconciliation
Optional remote access method if extending beyond the local lab; remote collection is not assumed by default
Bill of Materials
Windows PowerShell
Text editor (e.g., Visual Studio Code, Notepad++)
CSV file viewer (e.g., Microsoft Excel)
Build Steps
- Define the inventory scope before coding
This lab inventories traditional machine-wide applications registered under the 64-bit and 32-bit HKLM uninstall keys. Per-user installs, portable apps, Store/MSIX/AppX packages, and software without uninstall registration are separate evidence sources.
- Read both machine-wide uninstall registry views
Query HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\ and HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ using Get-ItemProperty. Do not use Win32_Product as the default inventory mechanism.
- Normalize useful fields
Return DisplayName, DisplayVersion, Publisher, InstallDate when present, UninstallString, registry source/view, and computer name. Drop entries without a meaningful display name and preserve source so duplicates can be investigated.
- Deduplicate conservatively
Group only records that match on meaningful identifiers such as display name/version/publisher and retain source details. Do not collapse different versions or architectures merely because names are similar.
- Export structured evidence and reconcile known software
Export CSV/JSON and compare the result against a small list of software you know is installed. Record expected software missing from registry inventory rather than silently declaring the inventory complete.
Validation
The script never calls Win32_Product
Both 64-bit and 32-bit HKLM uninstall views are queried
Known traditional applications appear with version/publisher/source
Duplicate handling does not erase legitimate side-by-side versions
The report states that per-user, portable, and MSIX/AppX coverage requires additional collection
A missing known application is captured as an inventory limitation or reconciliation exception
Troubleshooting
Unexpected duplicates: inspect registry source/view and version before deduplicating
Known app missing: determine whether it is per-user, MSIX/AppX, portable, or unregistered
For remote collection, solve authentication/remoting context separately rather than changing the local inventory logic
Cleanup or Rollback
Remove only generated inventory output files if they contain sensitive software details
Keep the script and reconciliation notes under version control
Next Improvements
Enhance the script to include additional software details such as installation date.
Integrate the script with a centralized logging system for better tracking.
Create a user-friendly interface for non-technical users to run the script.
