Get all software installed on a Windows computer, including programs, browser plugins, and installed packages. Note that this does not include other running processes in the processes table.
To learn more about queries, check this guide
SELECT name AS name, version AS version, 'Program (Windows)' AS type, 'programs' AS source FROM programs UNION SELECT name AS name, version AS version, 'Package (Python)' AS type, 'python_packages' AS source FROM python_packages UNION SELECT name AS name, version AS version, 'Browser plugin (IE)' AS type, 'ie_extensions' AS source FROM ie_extensions UNION SELECT name AS name, version AS version, 'Browser plugin (Chrome)' AS type, 'chrome_extensions' AS source FROM chrome_extensions UNION SELECT name AS name, version AS version, 'Browser plugin (Firefox)' AS type, 'firefox_addons' AS source FROM firefox_addons UNION SELECT name AS name, version AS version, 'Package (Chocolatey)' AS type, 'chocolatey_packages' AS source FROM chocolatey_packages;
# Get installed Windows programs from registry
$programs = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName } | ForEach-Object {
[PSCustomObject]@{
name = $_.DisplayName
version = $_.DisplayVersion
type = "Program (Windows)"
source = "programs"
}
}
# Get installed Python packages (if pip is available)
$python_pkgs = @()
try {
$pipOutput = & pip list --format=freeze 2>$null
if ($pipOutput) {
foreach ($line in $pipOutput) {
if ($line -match "^(.*?)==(.*)$") {
$python_pkgs += [PSCustomObject]@{
name = $matches[1]
version = $matches[2]
type = "Package (Python)"
source = "python_packages"
}
}
}
}
} catch {
# pip not found or error occurred
}
# Get Internet Explorer extensions from registry
$ie_extensions = @()
$ieRegKey = "HKLM:\SOFTWARE\Microsoft\Internet Explorer\Extensions"
if (Test-Path $ieRegKey) {
$ieData = Get-ItemProperty -Path $ieRegKey -ErrorAction SilentlyContinue
if ($ieData) {
foreach ($prop in $ieData.PSObject.Properties) {
# Using property name as the identifier; version info is not normally stored
$ie_extensions += [PSCustomObject]@{
name = $prop.Name
version = ""
type = "Browser plugin (IE)"
source = "ie_extensions"
}
}
}
}
# Get Chrome extensions by reading installed extension manifests
$chrome_extensions = @()
$chromeExtPath = Join-Path $env:LOCALAPPDATA "Google\Chrome\User Data\Default\Extensions"
if (Test-Path $chromeExtPath) {
$extDirs = Get-ChildItem -Path $chromeExtPath -Directory -ErrorAction SilentlyContinue
foreach ($ext in $extDirs) {
$versionDirs = Get-ChildItem -Path $ext.FullName -Directory -ErrorAction SilentlyContinue
foreach ($verDir in $versionDirs) {
$manifestPath = Join-Path $verDir.FullName "manifest.json"
if (Test-Path $manifestPath) {
try {
$manifest = Get-Content $manifestPath -Raw | ConvertFrom-Json
$extName = $manifest.name
$extVersion = $manifest.version
} catch {
$extName = $ext.Name
$extVersion = $verDir.Name
}
} else {
$extName = $ext.Name
$extVersion = $verDir.Name
}
$chrome_extensions += [PSCustomObject]@{
name = $extName
version = $extVersion
type = "Browser plugin (Chrome)"
source = "chrome_extensions"
}
}
}
}
# Get Firefox add-ons by locating extensions.json in profile directories and parsing it
$firefox_addons = @()
$firefoxProfilesPath = Join-Path $env:APPDATA "Mozilla\Firefox\Profiles"
if (Test-Path $firefoxProfilesPath) {
$profiles = Get-ChildItem -Path $firefoxProfilesPath -Directory -ErrorAction SilentlyContinue
foreach ($profile in $profiles) {
$extensionsJson = Join-Path $profile.FullName "extensions.json"
if (Test-Path $extensionsJson) {
try {
$json = Get-Content $extensionsJson -Raw | ConvertFrom-Json
if ($json.addons) {
foreach ($addon in $json.addons) {
if ($addon.type -eq "extension") {
$firefox_addons += [PSCustomObject]@{
name = $addon.name
version = $addon.version
type = "Browser plugin (Firefox)"
source = "firefox_addons"
}
}
}
}
} catch {
# Skip profiles with parsing issues
}
}
}
}
# Get installed Chocolatey packages (if choco is available)
$chocolatey_packages = @()
try {
$chocoOutput = & choco list --local-only --limit-output 2>$null
if ($chocoOutput) {
foreach ($line in $chocoOutput) {
if ($line -match "^(.*?)\|(.*)$") {
$chocolatey_packages += [PSCustomObject]@{
name = $matches[1]
version = $matches[2]
type = "Package (Chocolatey)"
source = "chocolatey_packages"
}
}
}
}
} catch {
# choco not found or error occurred
}
# Combine all results
$result = $programs + $python_pkgs + $ie_extensions + $chrome_extensions + $firefox_addons + $chocolatey_packages
# Output the result to stdout in table format
$result | Format-Table -AutoSize
PowerShell commands are currently work in progress, contributions welcome.