2008-09-22 7 views

Répondre

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

$app.Uninstall() 

Edit: Rob a trouvé une autre façon de le faire avec le paramètre Filter:

$app = Get-WmiObject -Class Win32_Product ` 
        -Filter "Name = 'Software Name'" 
+6

Après un peu de recherche, vous pouvez également utiliser la clause -filter de Get-WmiObject: $ app = Get-WmiObject -Class Win32_Product -filter "select * from Win32_Product WHERE nom = 'nom Software'" –

+4

Cette classe WMI prend FOREVER à enumerat e. Je suggère à Jeff que vous mettiez à jour votre code pour inclure l'astuce de Rob. – halr9000

+1

Je suis d'accord avec Jeff ... ma version ne semble pas fonctionner maintenant .... –

32

Pour fixer la deuxième méthode dans le poste de Jeff Hillman, vous pouvez soit faire:

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

Ou

$app = Get-WmiObject -Class Win32_Product ` 
        -Filter "Name = 'Software Name'" 
+0

Juste un heads-up ... J'ai trouvé que l'utilisation de l'option "-Query" au lieu de l'option "-Filter" ne renvoyait pas un WmiObject, donc il n'y avait pas de méthode "uninstall". –

6

Pour ajouter un peu à cet article, je devais être capable de supprimer le logiciel de plusieurs serveurs. J'ai utilisé la réponse de Jeff pour me conduire à ceci:

J'ai d'abord une liste de serveurs, je une requête AD, mais vous pouvez fournir le tableau de noms d'ordinateur comme vous le souhaitez:

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

Je en boucle à travers eux, en ajoutant le paramètre -ordinateur à 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'utilisé la propriété IdentifyingNumber faire correspondre au lieu du nom, juste pour être sûr que je désinstalle l'application correcte.

+0

Tout simplement adorable cette solution – Raffaeu

3

Je ferai ma petite contribution. J'avais besoin de retirer 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érera utile.

Notez que je dois David Stetler le mérite de ce script car il est basé sur son.

0

Utilisation:

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 est pas complètement testé, mais il a couru sous PowerShell 4.

J'ai couru 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 du logiciel de David Stetlers.

Non testé:

  1. Ne pas ajouter ids à l'appel de la fonction dans le script, en commençant au lieu du script avec les ID de paramètres
  2. Appeler le script avec plus de 1 nom de l'ordinateur pas automatiquement récupéré à partir de la fonction
  3. Récupération des données à partir du tuyau
  4. en utilisant des adresses IP pour se connecter au système

ce qu'il n'a pas:

  1. Il ne donne aucune information si le logiciel a effectivement é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 d'obtenir une erreur m'indiquant que l'appel d'une méthode pour une expression ayant une valeur NULL n'est pas possible. Au lieu de cela, j'ai utilisé Remove-WmiObject, qui semble accomplir la même chose.

ATTENTION: Sans un nom d'ordinateur étant donné qu'il supprime le logiciel de TOUS systèmes dans Active Directory.

4

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é this post de Sitaram Pamarthi avec un script à désinstaller si vous connaissez l'application guid. Il fournit également un autre script pour rechercher des applications très rapidement here.

Utilisez comme ceci:. \ 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"} 
} 
29

EDIT: Au fil des années, cette réponse a obtenu un assez grand nombre upvotes. Je voudrais ajouter quelques commentaires. Je ne l'ai pas utilisé PowerShell depuis, mais je me souviens observer quelques problèmes:

  1. S'il y a plus de matches que 1 pour le script ci-dessous, il ne fonctionne pas et vous devez ajouter le filtre PowerShell qui limite les résultats à 1. I 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, elle ne fonctionne pas. La raison pour laquelle il a été écrit comme ci-dessous est parce qu'il modifie le MSI à désinstaller sans intervention, ce qui n'est pas toujours le cas par défaut lors de l'utilisation de la chaîne de désinstallation native.

Utilisation de l'objet WMI prend toujours. C'est très rapide si vous connaissez juste le nom du programme que vous voulez 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} 
+1

Merci pour ça! J'essaye d'employer ceci avec '-comme" appNam * "' puisque la version est dans le nom et elle change, mais il ne semble pas trouver le programme. Des idées? – NSouth

+1

Recherchez la fonction -pour powershell, découvrez quel filtre utiliser et comment le faire correspondre correctement à votre chaîne. Il suffit d'utiliser le shell pour tester, et une fois que vous l'avez bien fait remplacer le -match :) – nickdnk

+2

Ceci est de l'or. Personnellement, je supprime le 'b' du '/ qb' pour que vous n'ayez pas à voir de dialogues. – WhiteHotLoveTiger

1

Sur la base de la réponse de Jeff Hillman:

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

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

Supposons que vous vouliez désinstaller Notepad++. Il suffit de taper ceci dans PowerShell:

> uninstall("notepad++")

Il faut juste savoir que Get-WmiObject peut prendre un certain temps, donc soyez patient!

0

Pour la plupart de mes programmes, les scripts de cet article ont fait l'affaire. Mais j'ai dû faire face à un programme hérité que je ne pouvais pas supprimer en utilisant msiexec.exe ou classe Win32_Product. (De quelque raison que je suis 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 le chemin du fichier de désinstallation 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 

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

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

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

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

$ uninstallResult - vous avoir le code de sortie. 0 est le succès

les commandes ci-dessus peuvent également exécuter à distance - je l'ai fait en utilisant la commande mais j'invoque crois que l'ajout de l'argument -computername peut travailler

1

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" 
Questions connexes