so I want to delete an app of which I do not know the product ID. I know you can delete an app by using msiexec.exe /x and then the product ID. How would I go about getting the product ID of a specific app also in commandline and storing the value in a variable so I can just place the variable in the delete command?
Thank in advance!!
CodePudding user response:
Here's a script I use. You have to know what the display name of the package is...like if you went to Remove Programs, what it's name would be. It works for my MSI packages that I create with WiX, but not all packages. You might consider winget
command if you are on Windows 10 . winget has an uninstall option.
param (
[Parameter(Mandatory = $true)]
[string] $ProductName,
[switch] $Interactive = $false,
[switch] $key = $false
)
$log_directory = "c:\users\public"
# $log_directory = "c:\erase\logs"
if ((-not $Interactive) -and (-not (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
{
$interactive = $true
# echo "Not elevated, needs to be interactive"
}
$found = $null
$productsKeyName = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products"
$rootKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($productsKeyName)
foreach ($productKeyName in $rootKey.GetSubKeyNames())
{
#$productKeyName
try
{
$installPropertiesKey = $rootKey.OpenSubKey("$productKeyName\InstallProperties")
if ($installPropertiesKey)
{
$displayName = [string] $installPropertiesKey.GetValue("DisplayName")
if ( (! [string]::IsNullOrEmpty($displayName)) -and ($displayName -eq $ProductName))
{
$found = $productKeyName
break
}
}
}
catch
{
}
finally
{
if ($installPropertiesKey) { $installPropertiesKey.Close() }
}
}
$rootKey.Close()
if (-not $found)
{
return "First search could not find $ProductName"
}
$localPackage = $null
if (! [string]::IsNullOrEmpty($found))
{
try
{
$regkey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("$productsKeyName\$found\InstallProperties")
$localPackage = $regkey.GetValue("LocalPackage")
}
catch
{
}
finally
{
if ($regkey) { $regkey.Close() }
}
}
if ($key)
{
return "Found key: $found"
}
if (![string]::IsNullOrEmpty($localPackage) -and (Test-Path $localPackage))
{
$logflags = "/lv*"
$logname = (Join-Path $log_directory "$ProductName_uninstall.log")
$args = @($logflags, $logname, "/X", $localPackage)
if (!$Interactive) { $args = "/q" }
&msiexec $args
}
else
{
"Could not find uninstall package: $ProductName"
}
CodePudding user response:
There's always get-package. No one knows about it but me. This should work for msi installs.
get-package *software* | uninstall-package
If you know the exact name, this should work. Uninstall-package doesn't take wildcards.
uninstall-package 'Citrix HDX RealTime Media Engine 2.9.400'
Sometimes, annoyingly, it prompts to install nuget first:
install-packageprovider nuget -force
If it's not an msi install, but a programs install, it takes a little more string mangling. You may have to add a '/S' or something for silent install at the end.
$prog,$myargs = -split (get-package 'Remote Support Jump Client *' |
% { $_.metadata['uninstallstring'] })
& $prog $myargs