Home > Mobile >  Delete an app on windows using powershell without querying win32
Delete an app on windows using powershell without querying win32

Time:03-18

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
  • Related