it-swarm-eu.dev

Jak mohu odinstalovat aplikaci pomocí PowerShell?

Existuje jednoduchý způsob, jak zavést do standardu ' Přidat nebo odebrat programy ' funkce pomocí PowerShell odinstalovat existující aplikaci ? Nebo zkontrolujte, zda je aplikace nainstalována?

113
Rob Paterson
$app = Get-WmiObject -Class Win32_Product | Where-Object { 
    $_.Name -match "Software Name" 
}

$app.Uninstall()

Edit: Rob našel jiný způsob, jak to provést s parametrem Filtr:

$app = Get-WmiObject -Class Win32_Product `
                     -Filter "Name = 'Software Name'"
135
Jeff Hillman

EDIT: V průběhu let se tato odpověď dostala docela málo upvotes. Chtěl bych přidat několik poznámek. Od té doby jsem nepoužíval PowerShell, ale pamatuji si na některé problémy:

  1. Pokud je v níže uvedeném skriptu více zápasů než 1, nefunguje to a musíte přidat filtr PowerShell, který omezuje výsledky na 1. Věřím, že je to -First 1, ale nejsem si jistý. Upravte.
  2. Pokud aplikace není nainstalována MSI, nefunguje. Důvod, proč byl napsán níže, je proto, že modifikuje MSI tak, aby odinstaloval bez zásahu, což není vždy výchozí případ při použití nativního odinstalačního řetězce.

Použití objektu WMI trvá věčně. To je velmi rychlé, pokud znáte název programu, který chcete odinstalovat.

$uninstall32 = gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "SOFTWARE NAME" } | select UninstallString
$uninstall64 = gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "SOFTWARE NAME" } | select UninstallString

if ($uninstall64) {
$uninstall64 = $uninstall64.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall64 = $uninstall64.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall64 /qb" -Wait}
if ($uninstall32) {
$uninstall32 = $uninstall32.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall32 = $uninstall32.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall32 /qb" -Wait}
38
nickdnk

Chcete-li opravit druhou metodu v příspěvku Jeffa Hillmana, můžete buď:

$app = Get-WmiObject 
            -Query "SELECT * FROM Win32_Product WHERE Name = 'Software Name'"

Nebo

$app = Get-WmiObject -Class Win32_Product `
                     -Filter "Name = 'Software Name'"
33
Robert Wagner

Chcete-li přidat trochu do tohoto příspěvku, musel jsem být schopen odstranit software z více serverů. Použil jsem Jeffovu odpověď, abych se k tomu dostal:

Nejprve jsem dostal seznam serverů, použil jsem dotaz AD query, ale můžete poskytnout pole názvů počítačů, jak chcete:

$computers = @("computer1", "computer2", "computer3")

Pak jsem s nimi prošel smyčkou, přidáním parametru -computer do dotazu gwmi:

foreach($server in $computers){
    $app = Get-WmiObject -Class Win32_Product -computer $server | Where-Object {
        $_.IdentifyingNumber -match "5A5F312145AE-0252130-432C34-9D89-1"
    }
    $app.Uninstall()
}

Použil jsem vlastnost IdentifyingNumber, aby odpovídal namísto jména, jen abych se ujistil, že jsem odinstaloval správnou aplikaci.

7
David Stetler

Zjistil jsem, že třída Win32_Product se nedoporučuje, protože spouští opravy a není optimalizována. Zdroj

Našel jsem tento příspěvek ze Sitaram Pamarthi se skriptem odinstalovat, pokud znáte aplikaci Guid. On také dodává další skript pro hledání aplikací opravdu rychle zde .

Použijte toto: uninstall.ps1 -GUID {C9E7751E-88ED-36CF-B610-71A1D262E906}

[cmdletbinding()]            

param (            

 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
 [string]$ComputerName = $env:computername,
 [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
 [string]$AppGUID
)            

 try {
  $returnval = ([WMICLASS]"\\$computerName\ROOT\CIMV2:win32_process").Create("msiexec `/x$AppGUID `/norestart `/qn")
 } catch {
  write-error "Failed to trigger the uninstallation. Review the error message"
  $_
  exit
 }
 switch ($($returnval.returnvalue)){
  0 { "Uninstallation command triggered successfully" }
  2 { "You don't have sufficient permissions to trigger the command on $Computer" }
  3 { "You don't have sufficient permissions to trigger the command on $Computer" }
  8 { "An unknown error has occurred" }
  9 { "Path Not Found" }
  9 { "Invalid Parameter"}
 }
6
Ricardo

Udělám svůj vlastní malý příspěvek. Potřeboval jsem odstranit seznam balíků ze stejného počítače. Toto je scénář, se kterým jsem přišel.

$packages = @("package1", "package2", "package3")
foreach($package in $packages){
  $app = Get-WmiObject -Class Win32_Product | Where-Object {
    $_.Name -match "$package"
  }
  $app.Uninstall()
}

Doufám, že se to ukáže jako užitečné.

Všimněte si, že dlužím Davidovi Stetlerovi kredit za tento skript, protože je založen na jeho.

3
Ben Key

Zde je skript PowerShell pomocí msiexec:

echo "Getting product code"
$ProductCode = Get-WmiObject win32_product -Filter "Name='Name of my Software in Add Remove Program Window'" | Select-Object -Expand IdentifyingNumber
echo "removing Product"
# Out-Null argument is just for keeping the power Shell command window waiting for msiexec command to finish else it moves to execute the next echo command
& msiexec /x $ProductCode | Out-Null
echo "uninstallation finished"
2
RBT
function Uninstall-App {
    Write-Output "Uninstalling $($args[0])"
    foreach($obj in Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") {
        $dname = $obj.GetValue("DisplayName")
        if ($dname -contains $args[0]) {
            $uninstString = $obj.GetValue("UninstallString")
            foreach ($line in $uninstString) {
                $found = $line -match '(\{.+\}).*'
                If ($found) {
                    $appid = $matches[1]
                    Write-Output $appid
                    start-process "msiexec.exe" -arg "/X $appid /qb" -Wait
                }
            }
        }
    }
}

Zavolejte to takto:

Uninstall-App "Autodesk Revit DB Link 2019"
2
Ehsan Irannejad

Na základě odpovědi Jeffa Hillmana:

Zde je funkce, kterou můžete přidat do souboru profile.ps1 nebo definovat v aktuální relaci PowerShell:

# Uninstall a Windows program
function uninstall($programName)
{
    $app = Get-WmiObject -Class Win32_Product -Filter ("Name = '" + $programName + "'")
    if($app -ne $null)
    {
        $app.Uninstall()
    }
    else {
        echo ("Could not find program '" + $programName + "'")
    }
}

Řekněme, že chcete odinstalovat Notepad ++ . Zadejte to do PowerShell:

> uninstall("notepad++")

Jen si uvědomte, že Get-WmiObject může nějakou dobu trvat, takže buďte trpěliví!

1
Kolob Canyon

Jeden řádek kódu:

get-package *notepad* |% { & $_.Meta.Attributes["UninstallString"]}
0

Použití:

function remove-HSsoftware{
[cmdletbinding()]
param(
[parameter(Mandatory=$true,
ValuefromPipeline = $true,
HelpMessage="IdentifyingNumber can be retrieved with `"get-wmiobject -class win32_product`"")]
[ValidatePattern('{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}}')]
[string[]]$ids,
[parameter(Mandatory=$false,
            ValuefromPipeline=$true,
            ValueFromPipelineByPropertyName=$true,
            HelpMessage="Computer name or IP adress to query via WMI")]
[Alias('hostname,CN,computername')]
[string[]]$computers
)
begin {}
process{
    if($computers -eq $null){
    $computers = Get-ADComputer -Filter * | Select dnshostname |%{$_.dnshostname}
    }
    foreach($computer in $computers){
        foreach($id in $ids){
            write-Host "Trying to uninstall sofware with ID ", "$id", "from computer ", "$computer"
            $app = Get-WmiObject -class Win32_Product -Computername "$computer" -Filter "IdentifyingNumber = '$id'"
            $app | Remove-WmiObject

        }
    }
}
end{}}
 remove-hssoftware -ids "{8C299CF3-E529-414E-AKD8-68C23BA4CBE8}","{5A9C53A5-FF48-497D-AB86-1F6418B569B9}","{62092246-CFA2-4452-BEDB-62AC4BCE6C26}"

Není to plně testováno, ale běží pod PowerShell 4.

Spustil jsem soubor PS1 tak, jak je zde vidět. Nechat jej načíst všechny systémy z AD a pokusit se odinstalovat více aplikací na všech systémech.

Použil jsem IdentifyingNumber k hledání softwarové příčiny vstupu David Stetlers.

Netestováno:

  1. Nepřidávejte ID do volání funkce ve skriptu, místo toho spusťte skript s ID parametrů
  2. Volání skriptu s více než jedním názvem počítače ne se automaticky načte z funkce
  3. Načítání dat z potrubí
  4. Použití IP adres pro připojení k systému

Co to neznamená:

  1. Neposkytuje žádné informace, pokud byl software skutečně nalezen v daném systému.
  2. Neposkytuje žádné informace o selhání nebo úspěchu deinstalace.

Nepodařilo se použít odinstalaci (). Snažím se, abych dostal chybu, která mi říká, že volání metody pro výraz, který má hodnotu NULL, není možné. Místo toho jsem použil Remove-WmiObject, který se zdá být stejný.

CAUTION: Bez názvu počítače odstraní software ze systému ALL ve službě Active Directory.

0
user3410872

Pro většinu mých programů to dělaly skripty v této poště. Ale musel jsem čelit staršímu programu, který jsem nemohl odstranit pomocí třídy msiexec.exe nebo třídy Win32_Product. (z nějakého důvodu jsem dostal exit 0, ale program tam pořád byl)

Moje řešení bylo použití třídy Win32_Process:

s pomocí nickdnk tento příkaz má dostat cestu k odinstalaci souboru exe:

64bit:

[array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString

32bit:

 [array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString

budete muset vyčistit výsledný řetězec:

$uninstallPath = $unInstallPathReg[0].UninstallString
$uninstallPath = $uninstallPath -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstallPath = $uninstallPath .Trim()

nyní, když máte příslušnou program odinstalovat cestu k souboru exe, můžete použít tento příkaz:

$uninstallResult = (Get-WMIObject -List -Verbose | Where-Object {$_.Name -eq "Win32_Process"}).InvokeMethod("Create","$unInstallPath")

$ uninstallResult - bude mít ukončovací kód. 0 je úspěch

výše uvedené příkazy lze také spouštět vzdáleně - použil jsem příkaz invoke, ale věřím, že přidání argumentu -počítačové jméno může fungovat

0
dsaydon