The common method used to return win32 application information from a Windows device via PowerShell is ‘gwmi win32_product.’ This returns the more pertinent IdentifyingNumber, Name, Vendor, Version, and Caption properties, as shown in the below example output.
IdentifyingNumber : {610803AF-1D3D-B3D1-1FB7-8614C4138ED7}
Name : User State Migration Tool (DesktopEditions)
Vendor : Microsoft
Version : 10.1.22621.1
Caption : User State Migration Tool (DesktopEditions)
However, Windows does have more information on these applications. Using the ‘wmic product get’ command, we can get a lot more information. Take a look at the below example output.
AssignmentType=1
Caption=User State Migration Tool (DesktopEditions)
Description=User State Migration Tool (DesktopEditions)
HelpLink=
HelpTelephone=
IdentifyingNumber={610803AF-1D3D-B3D1-1FB7-8614C4138ED7}
InstallDate=20230701
InstallDate2=
InstallLocation=
InstallSource=C:\ProgramData\Package Cache\{610803AF-1D3D-B3D1-1FB7-8614C4138ED7}v10.1.22621.1\Installers\
InstallState=5
Language=1033
LocalPackage=C:\WINDOWS\Installer\2885c7cf.msi
Name=User State Migration Tool (DesktopEditions)
PackageCache=C:\WINDOWS\Installer\2885c7cf.msi
PackageCode={C6FA666D-CB4B-43F7-9A50-3C53A44109B8}
PackageName=User State Migration Tool (DesktopEditions)-x86_en-us.msi
ProductID=
RegCompany=
RegOwner=
SKUNumber=
Transforms=
URLInfoAbout=
URLUpdateInfo=
Vendor=Microsoft
Version=10.1.22621.1
WordCount=0
I can imagine some scenarios in which this might be useful to return information about where an application was installed from, and on what date. Unfortunately, the command on its own does not return usable PowerShell objects that can be queried in dot notation. But, clearly we have all the information needed to reconstruct them!
I’ve put together this script with the intention of adding it to my Get-WinHostInfo-PsExec script to expand its capability. For the time being, it exists as a standalone script until I integrate the two. Here is the GitHub link: https://github.com/p8nflnt/Get-WinHostInfo-PsExec/blob/main/PsExec-WmicProductGet.ps1
<#
this is a standalone script to return results of 'wmic product get' via PsExec on a target host
and convert results back into usable PoSh objects.
Intended to be added to Get-WinHostInfo-PsExec script to expand capability
'wmic product get' returns additional app info like installation directory & date
#>
# clear variables
Get-Variable -Exclude PWD,*Preference | Remove-Variable -EA 0
# identify location of script
$scriptPath = Split-Path ($MyInvocation.MyCommand.Path) -Parent
# target hostname
$computerName = "<INSERT HOSTNAME>"
# function for timestamp
$timestamp = Get-Date -UFormat "%Y-%m-%d@%H%M"
# build output file path
$outputPath = "$scriptPath" + "\" + "$computerName" + "_" + "$timestamp" + ".json"
# get apps from target host w/ PsExec
$output = psexec.exe -s -nobanner -h \\$computerName Powershell.exe -Command "wmic product get /format:list" 2> $null
# if output is not null...
If ($output) {
# extract text lines
$textExtract = ($output -split "`r?`n").Trim() | Where-Object { $_ }
# reassemble text lines
$textExtract = $textExtract -join "`r`n"
# identify app blocks & drop empty blocks
$appBlocks = ($textExtract -split "(?msi)(?=^AssignmentType=\d+)") | Where-Object { $_ }
# initialize an empty array to store application objects
$appArray = @()
# process each application block
foreach ($block in $appBlocks) {
# split the block into lines
$lines = $block -split "`n"
# initialize an empty hashtable to store application properties
$appProps = @{}
# loop through each line and create a hashtable of properties and values
foreach ($line in $lines) {
$key, $value = $line -split '=', 2
if ($value) {
$appProps[$key] = $value
}
}
# create a custom object from the hashtable
$appObject = [PSCustomObject]$appProps
# add the application object to the array
$appArray += $appObject
}
# export app array to json & correct formatting
($appArray | ConvertTo-Json -depth 100).Replace('\r"','"') | Out-File "$outputPath" -Force
} Else {
Write-Host -ForegroundColor Red "No response from host."
}