PoshCode Archive  Artifact [3ba418ab6f]

Artifact 3ba418ab6fb44a45e250eb6eaf0b9a11bdc3154f2b6361be513683e915692615:

  • File List-AddRemovePrograms.ps1 — part of check-in [db369ae37e] at 2018-06-10 13:10:52 on branch trunk — This script creates a WMI Class Win32_AddRemovePrograms (and, on 64bit systems, a Win32_AddRemovePrograms32 for 32bit apps) which are backed by the registry provider. They can then be queried to list installed apps (and versions) and perform much faster than running the same queries using the PowerShell Registry provider. Additionally, they can be used in GPO policies, etc. (user: Joel Bennett size: 4056)

# encoding: ascii
# api: powershell
# title: List AddRemovePrograms
# description: This script creates a WMI Class Win32_AddRemovePrograms (and, on 64bit systems, a Win32_AddRemovePrograms32 for 32bit apps) which are backed by the registry provider.  They can then be queried to list installed apps (and versions) and perform much faster than running the same queries using the PowerShell Registry provider. Additionally, they can be used in GPO policies, etc.
# version: 0.1
# type: class
# author: Joel Bennett
# license: CC0
# x-poshcode-id: 2470
# x-archived: 2017-05-30T18:56:05
# x-published: 2011-01-21T13:59:00
#
#
if(!(gwmi -list Win32_AddRemovePrograms)) {

set-content $pwd\RegProgs.mof @'
#pragma namespace("\\\\.\\root\\cimv2")
instance of __Win32Provider as $Instprov
{
Name ="RegProv" ;
ClsID = "{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}" ;
};
instance of __InstanceProviderRegistration
{
Provider =$InstProv;
SupportsPut =TRUE;
SupportsGet =TRUE;
SupportsDelete =FALSE;
SupportsEnumeration = TRUE;
};

[dynamic, provider("RegProv"),
ProviderClsid("{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}"),
ClassContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")]
class Win32_AddRemovePrograms
{
[key]
string ProdID;
[PropertyContext("DisplayName")]
string DisplayName;
[PropertyContext("Publisher")]
string Publisher;
[PropertyContext("DisplayVersion")]
string Version;
[PropertyContext("UninstallString")]
string UninstallString;
[PropertyContext("EstimatedSize")]
string EstimatedSizeKb;
[PropertyContext("InstallDate")]
string InstallDate;
};
'@

#if((gwmi Win32_OperatingSystem -Property OSArchitecture).OSArchitecture -eq '64-bit') {
#if([intptr]::size -eq 8) {
if( test-path HKLM:\SOFTWARE\Wow6432Node ) {
add-content $pwd\RegProgs.mof @'
[dynamic, provider("RegProv"),
ProviderClsid("{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}"),
ClassContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall")]
class Win32_AddRemovePrograms32
{
[key]
string ProdID;
[PropertyContext("DisplayName")]
string DisplayName;
[PropertyContext("Publisher")]
string Publisher;
[PropertyContext("DisplayVersion")]
string Version;
[PropertyContext("UninstallString")]
string UninstallString;
[PropertyContext("EstimatedSize")]
string EstimatedSizeKb;
[PropertyContext("InstallDate")]
string InstallDate;
};
'@
}

Write-Warning "MOF compiler will be RunAs Administrator ..."
if(
    (new-object Security.Principal.WindowsPrincipal ([Security.Principal.WindowsIdentity]::GetCurrent())
    ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) 
) {
   mofcomp.exe $pwd\RegProgs.mof
} else {
   (start-process mofcomp.exe -verb runas -Args "$pwd\RegProgs.mof" -Passthru).WaitForExit() # -class:forceupdate 
}
}


## EXAMPLE:
## List installed 64 bit applications with ".NET" in the name (or 32bit on Windows 32bit)
Get-WmiObject Win32_AddRemovePrograms -filter "DisplayName like '%.NET%'" | Sort-Object DisplayName | Format-Table DisplayName, Version

if( test-path HKLM:\SOFTWARE\Wow6432Node ) {
## List installed 32 bit applications with ".NET" in the name (or nothing on Windows 32bit)
Get-WmiObject Win32_AddRemovePrograms32 -filter "DisplayName like '%.NET%'" | Sort-Object DisplayName | Format-Table DisplayName, Version

}


## NOTE: the alternative is a registry query which is much longer and more typing ... 
Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* DisplayName,Publisher,DisplayVersion,UninstallString,EstimatedSize,InstallDate -ea 0 | 
   Where-Object { $_.DisplayName -like "*.Net*" } | Sort-Object DisplayName | Format-Table DisplayName, DisplayVersion, EstimatedSize -AutoSize

## And which performs miserably, by comparison:   
# Duration Command
# -------- -------
# 0.23302s Get-WmiObject Win32_AddRemovePrograms32 -filter ...
# 1.04610s Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* ...