2008-09-22 16 views

Respuesta

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

$app.Uninstall() 

Editar: Rob encontró otra manera de hacerlo con el parámetro Filter:

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

Después de un poco de investigación también se puede utilizar la cláusula -Filter de Get-WmiObject: $ aplicación = Get-WmiObject -Class Win32_Product filtrar "seleccionar * de Win32_Product WHERE nombre = 'nombre software'" –

+4

Esta clase de WMI toma PARA SIEMPRE enumerar mi. Sugiero a Jeff que actualice su código para incluir la sugerencia de Rob. – halr9000

+1

Estoy de acuerdo con Jeff ... parece que mi versión no funciona ahora ... –

32

para arreglar el segundo método en el post de Jeff Hillman, que podría o bien hacer un:

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

O

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

Solo un aviso ... Encontré que usar la opción "-Query" en vez de "-Filter" no devolvía un WmiObject, por lo que no tenía un método de "desinstalación". –

6

Para agregar un poco a esta publicación, necesitaba poder eliminar el software de varios servidores. Solía ​​respuesta de Jeff me llevan a esto:

En primer lugar me dio una lista de servidores, utilicé una consulta AD, pero se puede proporcionar el conjunto de nombres de equipo que le apetezca:

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

Entonces en bucle a través de ellos, añadiendo el parámetro -computer a la consulta gwmi:

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

que utiliza la propiedad IdentifyingNumber a contrastar en lugar del nombre, sólo para estar seguro de que estaba desinstalar la aplicación correcta.

+0

Simplemente hermosa esta solución – Raffaeu

3

Haré mi propia pequeña contribución. Necesitaba eliminar una lista de paquetes de la misma computadora. Este es el guión que se me ocurrió.

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

Espero que esto sea útil.

Tenga en cuenta que le debo el crédito a David Stetler por este guión, ya que se basa en el suyo.

0

Uso:

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

No está completamente probado, pero corrió bajo PowerShell 4.

me he encontrado el archivo PS1 como se ve aquí. Permitiéndole recuperar todos los sistemas desde el AD e intentando desinstalar múltiples aplicaciones en todos los sistemas.

He utilizado IdentifyingNumber para buscar el software causante de la entrada de David Stetlers.

no han sido evaluados:

  1. No añadir identificadores de a la llamada de la función en el guión, en lugar de iniciar la secuencia de comandos con los ID de los parámetros
  2. llamar al script con más de 1 nombre del equipo no recuperado automáticamente de la función
  3. Recuperando datos de la tubería
  4. el uso de direcciones IP para conectarse al sistema

Lo que no es así:

  1. no da ninguna información si el software en realidad se encuentra en cualquier sistema dado.
  2. No proporciona ninguna información sobre el fracaso o el éxito de la desinstalación.

No pude utilizar la desinstalación(). Probé que recibí un error diciéndome que no es posible llamar a un método para una expresión que tiene un valor de NULL. En cambio, utilicé Remove-WmiObject, que parece lograr lo mismo.

PRECAUCIÓN: Sin un nombre de equipo dado que elimina el software desde TODAS sistemas en el Directorio Activo.

4

Descubrí que no se recomienda la clase Win32_Product porque desencadena reparaciones y no se optimiza la consulta. Source

Encontré this post de Sitaram Pamarthi con una secuencia de comandos para desinstalar si conoce la guía de la aplicación. También proporciona otro script para buscar aplicaciones realmente rápidas here.

uso como esto:. \ 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: A través de los años esta respuesta ha conseguido un buen número upvotes. Me gustaría agregar algunos comentarios. No he utilizado desde PowerShell, pero recuerdo la observación de algunos problemas:

  1. Si hay más partidos que 1 para la secuencia de comandos a continuación, que no funciona y hay que añadir el filtro de PowerShell que limita los resultados a 1. I creo que es -First 1 pero no estoy seguro. Siéntase libre de editar.
  2. Si la aplicación no está instalada por MSI, no funciona. La razón por la que se escribió a continuación es porque modifica el MSI para desinstalar sin intervención, que no siempre es el caso predeterminado cuando se utiliza la cadena de desinstalación nativa.

Utilizando el objeto WMI toma siempre. Esto es muy rápido si solo conoce el nombre del programa que desea desinstalar.

$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

¡Gracias por esto! Intento usar esto con '-like" appNam * "' ya que la versión está en el nombre y cambia, pero no parece encontrar el programa. ¿Algunas ideas? – NSouth

+1

Busque la función -like para powershell, descubra qué filtro usar y cómo hacer que coincida con su cadena correctamente. Simplemente use el shell para probar, y una vez que lo tenga bien, reemplace el -match :) – nickdnk

+2

Esto es oro. Personalmente, elimino la 'b' de '/ qb' para que no tenga que ver ningún cuadro de diálogo. – WhiteHotLoveTiger

1

Sobre la base de la respuesta de Jeff Hillman:

Aquí es una función sólo puede añadir a su profile.ps1 o definir en sesión de PowerShell actual:

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

Digamos que usted quiere desinstalar Notepad++. Sólo tienes que escribir esto en PowerShell:

> uninstall("notepad++")

Sólo ten en cuenta que Get-WmiObject puede llevar algún tiempo, así que tenga paciencia!

0

Para la mayoría de mis programas, los scripts en este Post hicieron el trabajo. Pero tuve que enfrentar un programa heredado que no pude eliminar utilizando la clase msiexec.exe o Win32_Product. (De alguna razón me dieron la salida 0, pero el programa todavía estaba allí)

Mi solución fue usar la clase Win32_Process:

con la ayuda de nickdnk este comando es para obtener la ruta del archivo exe de desinstalación:

64 bits:

[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 

tendrá que limpiar la cadena del resultado:

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

ahora cuando se tiene el programa ruta del archivo de desinstalación exe relevante puede utilizar este comando:

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

$ uninstallResult - se tener el código de salida. 0 es el éxito

los comandos anteriores también se pueden ejecutar de forma remota - lo hice utilizando la invocación de comandos, pero yo creo que la adición del argumento -computername puede trabajar

1

Aquí está la secuencia de comandos PowerShell usando 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" 
Cuestiones relacionadas