2008-09-22 13 views

ответ

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

$app.Uninstall() 

Edit: Роб нашел еще один способ сделать это с помощью параметра Filter:

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

После небольшого исследования вы можете также использовать предложение -filter из Get-WmiObject: $ приложение = Get-WmiObject -Class Win32_Product -filter "выберите * из Win32_Product где имя = 'Software Name'" – 2008-09-22 07:44:57

+4

Этот класс WMI берет FOREVER для перечисления е. Я предлагаю Джеффу, чтобы вы обновили свой код, чтобы включить подсказку Роба. – halr9000 2008-09-23 16:18:21

+1

Я согласен с Джеффом ... моя версия, похоже, сейчас не работает ... – 2008-10-01 05:32:57

32

Чтобы исправить второй метод в пост Джеффа Хиллман, вы можете либо сделать:

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

Или

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

Чтобы добавить немного к этому сообщению, мне нужно было удалить программное обеспечение с нескольких серверов. Я использовал ответ Джеффа, чтобы привести меня к этому:

Сначала я получил список серверов, я использовал AD запрос, но вы можете предоставить массив имен компьютеров, однако вы хотите:

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

Тогда я петельные через них, добавив -Компьютер параметр в запросе Gwmi:

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

Я использовал свойство IdentifyingNumber в соответствии с вместо имени, просто чтобы убедиться, что я деинсталлировать правильное применение.

3

Я сделаю свой собственный небольшой вклад. Мне нужно было удалить список пакетов с того же компьютера. Это сценарий, который я придумал.

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

Надеюсь, это окажется полезным.

Обратите внимание, что я обязан Дэвиду Стетлеру кредит за этот сценарий, поскольку он основан на его.

0

Использование:

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

Это не полностью протестированы, но он бежал под PowerShell 4.

Я запустить файл PS1, как это видно здесь. Позволяя ему восстановить все системы из AD и попытаться удалить несколько приложений во всех системах.

Я использовал идентификационный номер для поиска причины программного обеспечения для входа Дэвида Стетлерса.

Не тестировалось:

  1. Не добавлять идентификаторы для вызова функции в скрипте, вместо запуска сценария с идентификаторами параметров
  2. Вызов сценария с более чем 1 имя компьютера не автоматически извлеченной от функции
  3. извлечения данных из трубы
  4. помощью IP-адресов для подключения к системе

Что это не делает:

  1. Он не дает никакой информации, если программное обеспечение на самом деле был найден в любой системе.
  2. Информация о невыполнении или успешном дезактивации не предусмотрена.

Я не смог удалить uninstall(). Попытка, чтобы у меня была ошибка, сообщающая мне, что вызов метода выражения, имеющего значение NULL, невозможен. Вместо этого я использовал Remove-WmiObject, который, похоже, делает то же самое.

ВНИМАНИЕ: Без имени компьютера с учетом его удаляет программное обеспечение с ВСЕХ систем в Active Directory.

4

Я узнал, что класс Win32_Product не рекомендуется, потому что он запускает ремонт и не оптимизирован для запросов. Source

Я нашел this post от Sitaram Pamarthi со сценарием, который нужно удалить, если вы знаете приложение guid. Он также поставляет другой скрипт для быстрого поиска приложений here.

Используйте как это:. \ 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: На протяжении многих лет этот ответ получил довольно много upvotes. Я хотел бы добавить несколько комментариев. Я не использовал PowerShell с тех пор, но я помню, наблюдая некоторые вопросы:

  1. Если есть больше матчей, чем 1 для ниже сценария, он не работает, и вы должны добавить фильтр PowerShell, который ограничивает результаты 1. I Полагаю, что это -First 1, но я не уверен. Не стесняйтесь редактировать.
  2. Если приложение не установлено MSI, оно не работает. Причина, по которой это было написано ниже, заключается в том, что она изменяет MSI для удаления без вмешательства, что не всегда является случаем по умолчанию при использовании собственной строки удаления.

Использование объекта WMI принимает навсегда. Это очень быстро, если вы просто знаете имя программы, которую хотите удалить.

$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

На основании ответа Джеффа Хиллман:

Вот функция, вы можете просто добавить в свой profile.ps1 или определить в текущем сеансе 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 + "'") 
    } 
} 

Допустим, вы хотите удалить Notepad++. Просто введите это в PowerShell:

> uninstall("notepad++")

Просто надо знать, что Get-WmiObject может занять некоторое время, так что будьте терпеливы!

0

Для большинства моих программ скрипты в этом сообщении выполняли эту работу. Но мне пришлось столкнуться с устаревшей программой, которую я не смог удалить, используя класс msiexec.exe или Win32_Product. (С какой-то причине я получил выход 0, но программа все еще там)

Мое решение было использовать Win32_Process класс:

с помощью от nickdnk эта команда должна получить путь удаления 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 

вам придется очистить строку результата:

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

теперь, когда у вас есть соответствующий программного путь удаления EXE файл вы можете использовать эту команду:

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

$ uninstallResult - будет имеют код выхода. 0 успех

вышеуказанные команды могут работать удаленно - я сделал это с помощью команды вызова, но я считаю, что добавление аргумента -computername может работать

1

Вот скрипт PowerShell с помощью 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"