Comment puis-je désinstaller une application en utilisant PowerShell?

est-ce qu'il y a un moyen simple d'accrocher dans la norme ' ajouter ou supprimer des programmes 'fonctionnalité utilisant PowerShell à désinstaller une application existante ? Ou pour vérifier si l'application est installée?

107
demandé sur Stein Åsmul 2008-09-22 11:04:06

10 réponses

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

$app.Uninstall()

Edit: Rob trouvé un autre moyen de le faire avec le paramètre de Filtre:

$app = Get-WmiObject -Class Win32_Product `
                     -Filter "Name = 'Software Name'"
126
répondu Jeff Hillman 2014-08-18 14:39:42

EDIT: au fil des ans, cette réponse a reçu pas mal d'éloges. Je voudrais ajouter quelques commentaires. Je n'ai pas utilisé PowerShell depuis, mais je me souviens avoir observé quelques problèmes:

  1. S'il y a plus de correspondances que 1 pour le script ci-dessous, cela ne fonctionne pas et vous devez ajouter le filtre PowerShell qui limite les résultats à 1. Je crois que c'est -First 1 mais je ne suis pas sûr. N'hésitez pas à modifier.
  2. Si l'application n'est pas installée par MSI ça ne marche pas. La raison pour laquelle il a été écrit comme ci-dessous est qu'il modifie le MSI pour désinstaller sans intervention, ce qui n'est pas toujours le cas par défaut lorsque vous utilisez la chaîne native de désinstallation.

L'utilisation de L'objet WMI prend une éternité. C'est très rapide si vous savez le nom du programme que vous souhaitez désinstaller.

$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}
34
répondu nickdnk 2016-12-13 13:12:51

pour réparer la deuxième méthode dans le post de Jeff Hillman, vous pouvez soit faire un:

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

ou

$app = Get-WmiObject -Class Win32_Product `
                     -Filter "Name = 'Software Name'"
33
répondu Robert Wagner 2014-08-18 14:39:58

pour ajouter un peu à ce post, je devais être en mesure de supprimer le logiciel de plusieurs serveurs. J'ai utilisé la réponse de Jeff pour me mener à ceci:

D'abord j'ai eu une liste de serveurs, j'ai utilisé une requête AD , mais vous pouvez fournir le tableau de noms d'ordinateurs comme vous voulez:

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

puis je les ai parcourus en boucle, ajoutant le paramètre-computer à la requête gwmi:

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

j'ai utilisé le Identifier la propriété number à comparer à la place du nom, juste pour être sûr que je désinstallais l'application correcte.

7
répondu David Stetler 2016-12-19 19:02:42

j'ai découvert que la classe Win32_Product n'est pas recommandée car elle déclenche des réparations et n'est pas optimisée pour les requêtes. Source

j'ai trouvé ce post de Sitaram Pamarthi avec un script pour désinstaller si vous connaissez l'application. Il fournit également un autre script pour rechercher des applications vraiment rapide ici .

utiliser comme ceci:. \désinstaller.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"}
 }
5
répondu Ricardo 2014-08-22 14:22:04

je ferai ma petite contribution. J'avais besoin de supprimer une liste de paquets du même ordinateur. C'est le script que j'ai trouvé.

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

j'espère que cela s'avère utile.

notez que je dois à David Stetler le crédit de ce script puisqu'il est basé sur le sien.

3
répondu Ben Key 2014-08-18 14:40:37

voici le script PowerShell en utilisant 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
répondu RBT 2017-07-13 12:32:29

D'après la réponse de Jeff Hillman:

Voici une fonction que vous pouvez simplement ajouter à votre profile.ps1 ou définir dans la session PowerShell actuelle:

# 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 + "'")
    }
}

disons que vous vouliez désinstaller Notepad++ . Tapez ceci dans PowerShell:

> uninstall("notepad++")

soyez juste conscient que Get-WmiObject peut prendre un certain temps, alors soyez patient!

1
répondu Kolob Canyon 2016-12-19 19:09:17

utiliser:

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}"

il n'est pas entièrement testé, mais il fonctionne sous PowerShell 4.

j'ai lancé le fichier PS1 comme on le voit ici. Le laisser récupérer tous les systèmes du AD et essayer de désinstaller plusieurs applications sur tous les systèmes.

j'ai utilisé le numéro D'identification pour rechercher la cause logicielle de David Stetlers input.

non testé:

  1. ne pas ajouter d'ids à l'appel de la fonction dans le script, au lieu de démarrer le script avec des IDS de paramètre
  2. l'Appel du script, avec plus de 1 nom de l'ordinateur pas automatiquement récupérées à partir de la fonction
  3. extraire des données du tuyau
  4. utiliser des adresses IP pour se connecter au système

Ce qui n'est pas:

  1. Il ne le précise pas si le logiciel a été trouvé sur un système donné.
  2. il ne donne aucune information sur l'échec ou le succès de la désinstallation.

Je n'ai pas pu utiliser uninstall(). Essayer que j'ai une erreur me disant qu'appeler une méthode pour une expression qui a une valeur de NULL n'est pas possible. Au lieu de cela, j'ai utilisé Remove-WmiObject, qui semble accomplir la même chose.

CAUTION : sans un nom d'ordinateur donné il supprime le logiciel de tous systèmes dans le Active Directory.

0
répondu user3410872 2016-12-19 19:08:00

Pour la Plupart de mes programmes, les scripts dans ce Post fait le travail. Mais j'ai dû faire face à un programme que je ne pouvais pas supprimer en utilisant msiexec.classe exe ou Win32_Product. (de quelque raison j'ai obtenu la sortie 0 mais le programme était toujours là)

ma solution était D'utiliser la classe Win32_Process:

avec l'aide de nickdnk cette commande est d'obtenir la désinstallation exe chemin de fichier:

64bit:

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

32 bits:

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

vous devrez nettoyer la chaîne de résultat:

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

maintenant que vous avez le programme de désinstallation exe chemin de fichier vous pouvez utiliser cette commande:

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

$ désinstallallresult-aura le code de sortie. 0 est la réussite

les commandes ci - dessus peuvent également être exécutées à distance- je l'ai fait en utilisant invoquer la commande mais je crois que l'ajout de l'argument-computername peut fonctionner

0
répondu dsaydon 2017-06-26 07:48:44