Как удалить приложение с помощью PowerShell?

Есть ли простой способ подключиться к стандартной функциональности Установка и удаление программ "с помощью PowerShell до удалить существующее приложение? Или проверить, установлено ли приложение?

Ответ 1

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

$app.Uninstall()

Изменить: Роб нашел другой способ сделать это с помощью параметра Filter:

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

Ответ 2

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

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

или

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

Ответ 3

РЕДАКТИРОВКА: На протяжении многих лет этот ответ получил немало оборотов. Я хотел бы добавить несколько комментариев. Я не использовал PowerShell с тех пор, но я помню, что наблюдал некоторые проблемы:

  • Если для ниже script больше совпадений, чем 1, это не работает, и вы должны добавить фильтр PowerShell, который ограничивает результаты до 1. Я считаю, что это -First 1, но я не уверен. Не стесняйтесь редактировать.
  • Если приложение не установлено 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}

Ответ 4

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

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

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

Затем я зациклился на них, добавив параметр -computer в запрос 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 для сопоставления вместо имени, просто чтобы убедиться, что я удалял правильное приложение.

Ответ 5

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

Я нашел этот пост от Sitaram Pamarthi с помощью script, чтобы удалить, если вы знаете приложение guid. Он также поставляет еще один script для быстрого поиска приложений здесь.

Используйте это:.\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

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

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

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

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

Ответ 7

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

Здесь вы можете просто добавить свой 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 может занять некоторое время, поэтому будьте терпеливы!

Ответ 8

Вот PowerShell script, используя 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"

Ответ 9

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

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 и попытаться удалить несколько приложений во всех системах.

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

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

  • Не добавлять идентификаторы к вызову функции в script, вместо этого запускать script с идентификаторами параметров
  • Вызов script с более чем одним именем компьютера не автоматически извлекается из функции
  • Извлечение данных из канала
  • Использование IP-адресов для подключения к системе

Что это не значит:

  • Он не дает никакой информации, если программное обеспечение действительно было найдено в любой системе.
  • Он не предоставляет никакой информации о сбое или удалении деинсталляции.

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

ПРЕДОСТЕРЕЖЕНИЕ: без имени компьютера, если оно удаляет программное обеспечение из систем ВСЕ в Active Directory.

Ответ 10

В большинстве моих программ скрипты в этой Почте выполняли эту работу. Но мне пришлось столкнуться с устаревшей программой, которую я не смог удалить, используя класс 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 - успех

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