emergency fix for Uninstall-MSI
This commit is contained in:
@@ -887,99 +887,108 @@ Function Get-GUIDFromMSIUninstallString ([string]$str) {
|
||||
Return $retval
|
||||
}
|
||||
|
||||
#Function Uninstall-MSI {
|
||||
# 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
|
||||
# $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
|
||||
#
|
||||
# # Exit if we can't find any software at all
|
||||
# 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
|
||||
# $INSTALLED_APPS = @()
|
||||
#
|
||||
# Foreach ( $reg in $UNINSTALL_KEYS ) {
|
||||
# # Get the uninstall key
|
||||
# $REG_PROPERTY = Get-ItemProperty -Path $reg.PSPath
|
||||
#
|
||||
# # Skip apps missing both the UninstallString and ModifyPath
|
||||
# If ( [string]::IsNullOrEmpty($REG_PROPERTY.UninstallString) -and [string]::IsNullOrEmpty($REG_PROPERTY.ModifyPath) ) { Continue }
|
||||
#
|
||||
# # Determine if the app is installed via MSI
|
||||
# If ( $REG_PROPERTY.WindowsInstaller -eq 1 ) {
|
||||
#
|
||||
# $MSI = $true
|
||||
#
|
||||
# # Get the product code from the UninstallString or ModifyPath if the app is installed via MSI
|
||||
# If ( ![string]::IsNullOrEmpty($REG_PROPERTY.UninstallString) ) { $PRODUCT_CODE = $(Get-GUIDFromMSIUninstallString -str $REG_PROPERTY.UninstallString) }
|
||||
#
|
||||
# # Get the product code from the ModifyPath
|
||||
# ElseIf ( ![string]::IsNullOrEmpty($REG_PROPERTY.ModifyPath) ) { $PRODUCT_CODE = $(Get-GUIDFromMSIUninstallString -str $REG_PROPERTY.ModifyPath) }
|
||||
#
|
||||
# # Don't add an app with an unknown product code
|
||||
# If ( [string]::IsNullOrEmpty($PRODUCT_CODE) ) { Continue }
|
||||
#
|
||||
# } Else { $MSI = $false }
|
||||
#
|
||||
# # Get a usable name for the entry
|
||||
# If ( ![string]::IsNullOrEmpty($REG_PROPERTY.DisplayName) ) {
|
||||
# $AppName = $REG_PROPERTY.DisplayName
|
||||
# } ElseIf ( ![string]::IsNullOrEmpty($REG_PROPERTY.Name) ) {
|
||||
# $AppName = $REG_PROPERTY.DisplayName
|
||||
# } Else {
|
||||
# $AppName = '[unknown]'
|
||||
# }
|
||||
#
|
||||
# $customObject = [PSCustomObject]@{
|
||||
# MSI = $MSI
|
||||
# DisplayName = $AppName
|
||||
# UninstallString = $REG_PROPERTY.UninstallString
|
||||
# ModifyPath = $REG_PROPERTY.ModifyPath
|
||||
# ProductCode = $PRODUCT_CODE
|
||||
# }
|
||||
#
|
||||
# # Cleanup object properties
|
||||
# #If ( $customObject.)
|
||||
#
|
||||
# $INSTALLED_APPS += $customObject
|
||||
#
|
||||
# }
|
||||
# }
|
||||
# PROCESS {
|
||||
# Foreach ( $app in $APP_NAMES ) {
|
||||
# Foreach ( $installed_app in $INSTALLED_APPS ) {
|
||||
#
|
||||
# # Do not add apps which name does not match the one we're looking for
|
||||
# Switch ( $Match ) {
|
||||
# $true { If ( !($installed_app.DisplayName -match $app) ) { Continue } }
|
||||
# $false { If ( !($installed_app.DisplayName -ilike $app) ) { Continue } }
|
||||
# }
|
||||
#
|
||||
# $DisplayName = $installed_app.DisplayName
|
||||
# $UninstallString = $installed_app.UninstallString
|
||||
# $ProductCode = $installed_app.ProductCode
|
||||
#
|
||||
# # Print out uninstall string for unsupported apps
|
||||
# If ( $installed_app.UninstallSupported -eq $false ) {
|
||||
# Write-Output "Cannot uninstall ""${DisplayName}""`n UninstallString: ${UninstallString}"
|
||||
# Continue
|
||||
# }
|
||||
#
|
||||
# # Uninstall the app
|
||||
# Write-Output "Uninstalling ""${DisplayName}"" with product code: ${ProductCode}"
|
||||
# $arguments = '/X{' + $ProductCode + '} /qn /norestart'
|
||||
# Try { Start-Process -FilePath "msiexec.exe" -ArgumentList $arguments -Wait }
|
||||
# Catch { Write-Error $_.Exception.Message }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#}
|
||||
Function Get-GUIDFromMSIUninstallString ([string]$str) {
|
||||
$start = $str.IndexOf('{') + 1
|
||||
$end = $str.IndexOf('}')
|
||||
$retval = $str.Substring($start, $end - $start)
|
||||
If ( $retval.Length -ne 36 ) { $retval = $null }
|
||||
Return $retval
|
||||
}
|
||||
Function Uninstall-MSI {
|
||||
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
|
||||
$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
|
||||
|
||||
# Exit if we can't find any software at all
|
||||
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
|
||||
$INSTALLED_APPS = @()
|
||||
|
||||
Foreach ( $reg in $UNINSTALL_KEYS ) {
|
||||
# Get the uninstall key
|
||||
$REG_PROPERTY = Get-ItemProperty -Path $reg.PSPath
|
||||
|
||||
# Skip apps missing both the UninstallString and ModifyPath
|
||||
If ( [string]::IsNullOrEmpty($REG_PROPERTY.UninstallString) -and [string]::IsNullOrEmpty($REG_PROPERTY.ModifyPath) ) { Continue }
|
||||
|
||||
# Determine if the app is installed via MSI
|
||||
If ( $REG_PROPERTY.WindowsInstaller -eq 1 ) {
|
||||
|
||||
$MSI = $true
|
||||
|
||||
# Get the product code from the UninstallString or ModifyPath if the app is installed via MSI
|
||||
If ( ![string]::IsNullOrEmpty($REG_PROPERTY.UninstallString) ) { $PRODUCT_CODE = $(Get-GUIDFromMSIUninstallString -str $REG_PROPERTY.UninstallString) }
|
||||
|
||||
# Get the product code from the ModifyPath
|
||||
ElseIf ( ![string]::IsNullOrEmpty($REG_PROPERTY.ModifyPath) ) { $PRODUCT_CODE = $(Get-GUIDFromMSIUninstallString -str $REG_PROPERTY.ModifyPath) }
|
||||
|
||||
# Don't add an app with an unknown product code
|
||||
If ( [string]::IsNullOrEmpty($PRODUCT_CODE) ) { Continue }
|
||||
|
||||
} Else { $MSI = $false }
|
||||
|
||||
# Get a usable name for the entry
|
||||
If ( ![string]::IsNullOrEmpty($REG_PROPERTY.DisplayName) ) {
|
||||
$AppName = $REG_PROPERTY.DisplayName
|
||||
} ElseIf ( ![string]::IsNullOrEmpty($REG_PROPERTY.Name) ) {
|
||||
$AppName = $REG_PROPERTY.DisplayName
|
||||
} Else {
|
||||
$AppName = '[unknown]'
|
||||
}
|
||||
|
||||
$customObject = [PSCustomObject]@{
|
||||
MSI = $MSI
|
||||
DisplayName = $AppName
|
||||
UninstallString = $REG_PROPERTY.UninstallString
|
||||
ModifyPath = $REG_PROPERTY.ModifyPath
|
||||
ProductCode = $PRODUCT_CODE
|
||||
}
|
||||
|
||||
# TODO: Cleanup object properties
|
||||
|
||||
$INSTALLED_APPS += $customObject
|
||||
|
||||
}
|
||||
}
|
||||
PROCESS {
|
||||
Foreach ( $app in $APP_NAMES ) {
|
||||
Foreach ( $installed_app in $INSTALLED_APPS ) {
|
||||
$uninstall = $false
|
||||
|
||||
# Do not add apps whose name does not match the one we're looking for
|
||||
Switch ( $Match ) {
|
||||
$true { If ( $installed_app.DisplayName -match $app ) { $uninstall = $true } }
|
||||
$false { If ( $installed_app.DisplayName -ilike $app ) { $uninstall = $true } }
|
||||
}
|
||||
|
||||
# Print out uninstall string for unsupported apps
|
||||
If ( ($uninstall) -and ($installed_app.UninstallSupported -eq $false) ) {
|
||||
Write-Output "Cannot uninstall ""${DisplayName}""`n UninstallString: ${UninstallString}"
|
||||
$uninstall = $false
|
||||
}
|
||||
|
||||
If ( $uninstall ) {
|
||||
$DisplayName = $installed_app.DisplayName
|
||||
$UninstallString = $installed_app.UninstallString
|
||||
$ProductCode = $installed_app.ProductCode
|
||||
|
||||
# Uninstall the app
|
||||
Write-Output "Uninstalling ""${DisplayName}"" with product code: ${ProductCode}"
|
||||
$arguments = '/X{' + $ProductCode + '} /qn /norestart'
|
||||
Try { Start-Process -FilePath "msiexec.exe" -ArgumentList $arguments -Wait }
|
||||
Catch { Write-Error $_.Exception.Message }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Reboot an endpoint based on the amount of time it has been running without a reboot
|
||||
Function Restart-EndpointOnUptime ([timespan]$MaxUptime) {
|
||||
|
||||
Reference in New Issue
Block a user