updates to Uninstall-MSI
This commit is contained in:
@@ -892,14 +892,19 @@ Function Get-GUIDFromMSIUninstallString ([string]$str) {
|
|||||||
Return $retval
|
Return $retval
|
||||||
}
|
}
|
||||||
|
|
||||||
Function Uninstall-MSI ([Parameter(ValueFromPipeline=$true)][string[]]$APP_NAMES) {
|
Function Uninstall-MSI {
|
||||||
PROCESS {
|
param(
|
||||||
|
[Parameter(ValueFromPipeline=$true,Mandatory=$true)][string[]]$APP_NAMES,
|
||||||
|
[Parameter(ValueFromPipeline=$false,Mandatory=$false)][switch]$Match,
|
||||||
|
[Parameter(ValueFromPipeline=$false,Mandatory=$false)][switch]$IncludeNonMSI
|
||||||
|
)
|
||||||
|
BEGIN {
|
||||||
# Get all of the uninstall registry keys
|
# Get all of the uninstall registry keys
|
||||||
$UNINSTALL_KEYS = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall -ErrorAction SilentlyContinue
|
$UNINSTALL_KEYS = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall -ErrorAction SilentlyContinue
|
||||||
$UNINSTALL_KEYS += Get-ChildItem -Path HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall -ErrorAction SilentlyContinue
|
$UNINSTALL_KEYS += Get-ChildItem -Path HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
# Exit if we can't find any software at all
|
# Exit if we can't find any software at all
|
||||||
If ( $UNINSTALL_KEYS.Length -eq 0 ) { Write-Error "Attempted to uninstall ${APP_NAMES} but could not find any installed apps in the Windows Registry" ; Return }
|
If ( $UNINSTALL_KEYS.Length -eq 0 ) { Write-Error "Could not find any installed apps in the Windows Registry" ; Return }
|
||||||
|
|
||||||
# Array to store custom objects about each installed MSI app
|
# Array to store custom objects about each installed MSI app
|
||||||
$INSTALLED_APPS = @()
|
$INSTALLED_APPS = @()
|
||||||
@@ -908,39 +913,52 @@ Function Uninstall-MSI ([Parameter(ValueFromPipeline=$true)][string[]]$APP_NAMES
|
|||||||
# Get the uninstall key
|
# Get the uninstall key
|
||||||
$REG_PROPERTY = Get-ItemProperty -Path $reg.PSPath
|
$REG_PROPERTY = Get-ItemProperty -Path $reg.PSPath
|
||||||
|
|
||||||
# Guards to prevent working with incompatible apps
|
# Skip apps missing both the UninstallString and ModifyPath
|
||||||
If ( [string]::IsNullOrEmpty($REG_PROPERTY.UninstallString) -and [string]::IsNullOrEmpty($REG_PROPERTY.ModifyPath) ) { Continue }
|
If ( [string]::IsNullOrEmpty($REG_PROPERTY.UninstallString) -and [string]::IsNullOrEmpty($REG_PROPERTY.ModifyPath) ) { Continue }
|
||||||
|
|
||||||
# Determine if the app is installed via MSI
|
# Determine if the app is installed via MSI
|
||||||
If ( $REG_PROPERTY.WindowsInstaller -eq 1 ) { $UNINSTALL_SUPPORTED = $true } Else { $UNINSTALL_SUPPORTED = $false }
|
If ( $REG_PROPERTY.WindowsInstaller -eq 1 ) {
|
||||||
|
|
||||||
|
$MSI = $true
|
||||||
|
|
||||||
# Get the product code from the UninstallString or ModifyPath if the app is installed via MSI
|
# Get the product code from the UninstallString or ModifyPath if the app is installed via MSI
|
||||||
[string]$PRODUCT_CODE = $null
|
If ( ![string]::IsNullOrEmpty($REG_PROPERTY.UninstallString) ) { $PRODUCT_CODE = $(Get-GUIDFromMSIUninstallString -str $REG_PROPERTY.UninstallString) }
|
||||||
If ( ![string]::IsNullOrEmpty($REG_PROPERTY.UninstallString) -and $UNINSTALL_SUPPORTED ) { $PRODUCT_CODE = $(Get-GUIDFromMSIUninstallString -str $REG_PROPERTY.UninstallString) }
|
|
||||||
|
|
||||||
# Get the product code from the ModifyPath
|
# Get the product code from the ModifyPath
|
||||||
ElseIf ( ![string]::IsNullOrEmpty($REG_PROPERTY.ModifyPath) -and $UNINSTALL_SUPPORTED ) { $PRODUCT_CODE = $(Get-GUIDFromMSIUninstallString -str $REG_PROPERTY.ModifyPath) }
|
ElseIf ( ![string]::IsNullOrEmpty($REG_PROPERTY.ModifyPath) ) { $PRODUCT_CODE = $(Get-GUIDFromMSIUninstallString -str $REG_PROPERTY.ModifyPath) }
|
||||||
|
|
||||||
# Additional guard to prevent adding an app with no product code
|
# Don't add an app with an unknown product code
|
||||||
If ( [string]::IsNullOrEmpty($PRODUCT_CODE) ) { Continue }
|
If ( [string]::IsNullOrEmpty($PRODUCT_CODE) ) { Continue }
|
||||||
|
|
||||||
|
} Else { $MSI = $false }
|
||||||
|
|
||||||
|
# Get a usable name for the entry
|
||||||
|
If ( $REG_PROPERTY.DisplayName)
|
||||||
|
|
||||||
$customObject = [PSCustomObject]@{
|
$customObject = [PSCustomObject]@{
|
||||||
UninstallSupported = $UNINSTALL_SUPPORTED
|
MSI = $MSI
|
||||||
DisplayName = $REG_PROPERTY.DisplayName
|
DisplayName = $REG_PROPERTY.DisplayName
|
||||||
UninstallString = $REG_PROPERTY.UninstallString
|
UninstallString = $REG_PROPERTY.UninstallString
|
||||||
ModifyPath = $REG_PROPERTY.ModifyPath
|
ModifyPath = $REG_PROPERTY.ModifyPath
|
||||||
ProductCode = $PRODUCT_CODE
|
ProductCode = $PRODUCT_CODE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Cleanup object properties
|
||||||
|
If ( $customObject.)
|
||||||
|
|
||||||
$INSTALLED_APPS += $customObject
|
$INSTALLED_APPS += $customObject
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
PROCESS {
|
||||||
Foreach ( $app in $APP_NAMES ) {
|
Foreach ( $app in $APP_NAMES ) {
|
||||||
Foreach ( $installed_app in $INSTALLED_APPS ) {
|
Foreach ( $installed_app in $INSTALLED_APPS ) {
|
||||||
|
|
||||||
# Make sure the DisplayName matches what we're looking for
|
# Do not add apps which name does not match the one we're looking for
|
||||||
If ( !($installed_app.DisplayName -ilike $app) ) { Continue }
|
Switch ( $Match ) {
|
||||||
|
$true { If ( !($installed_app.DisplayName -match $app) ) { Continue } }
|
||||||
|
$false { If ( !($installed_app.DisplayName -ilike $app) ) { Continue } }
|
||||||
|
}
|
||||||
|
|
||||||
$DisplayName = $installed_app.DisplayName
|
$DisplayName = $installed_app.DisplayName
|
||||||
$UninstallString = $installed_app.UninstallString
|
$UninstallString = $installed_app.UninstallString
|
||||||
|
|||||||
Reference in New Issue
Block a user