PowerShell을 사용하여 응용 프로그램을 제거하려면 어떻게해야합니까?


136

PowerShell을 사용하여 표준 ' 프로그램 추가 / 제거 '기능에 연결하여 기존 응용 프로그램제거하는 간단한 방법이 있습니까? 아니면 응용 프로그램이 설치되어 있는지 확인 하시겠습니까?

답변:


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

$app.Uninstall()

편집 : Rob은 Filter 매개 변수를 사용하여 다른 방법을 찾았습니다.

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

1
이것은 경우에 따라 이름 대신 식별 번호를 사용하는 것이 좋습니다.
욕조

6
연구의 조금 후에는 GET-WmiObject를의 필터 - 절 사용할 수 있습니다 : $ 응용 프로그램 = GET-WmiObject를 -Class Win32_Product와 -filter "를 선택 * Win32_Product와에서 WHERE 이름 = '소프트웨어 이름'"
롭 패터슨

8
WMI를 살펴보면 MSI를 통해 설치된 제품에서만 작동합니다.
EBGreen

7
이 WMI 클래스는 영원히 열거됩니다. Jeff에게 Rob의 팁을 포함하도록 코드를 업데이트 할 것을 제안합니다.
halr9000

4
(gwmi Win32_Product | ? Name -eq "Software").uninstall() 작은 코드 골프.
roundar

51

편집 : 몇 년 동안이 대답은 꽤 많은 공감을 얻었습니다. 의견을 추가하고 싶습니다. 이후 PowerShell을 사용하지 않았지만 몇 가지 문제를 관찰 한 것을 기억합니다.

  1. 아래 스크립트에 대해 1보다 많은 일치 항목이있는 경우 작동하지 않으며 결과를 1로 제한하는 PowerShell 필터를 추가해야합니다. 믿지만 -First 1확실하지 않습니다. 자유롭게 편집하십시오.
  2. 응용 프로그램이 MSI에 의해 설치되어 있지 않으면 작동하지 않습니다. 다음과 같이 작성된 이유는 개입없이 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
감사합니다! -like "appNam*"버전이 이름에 있고 버전이 바뀌기 때문에 이것을 사용하려고 하지만 프로그램을 찾지 못하는 것 같습니다. 어떤 아이디어?
NSouth

1
powershell에 대해 -like 기능을 찾고 문자열을 올바르게 일치시키는 방법을 사용할 필터를 찾으십시오. 쉘을 사용하여 테스트하고, 일단
올바르게 찾으면

2
이것은 금입니다. 개인적으로 '/ qb'에서 'b'를 제거하므로 대화 상자를 볼 필요가 없습니다.
WhiteHotLoveTiger

훨씬 빠른 :-)
Oscar Foley

3
프롬프트와 "제거 할 대상"정보가있는 .ps1 스크립트로 이것을 설정했습니다. gist.github.com/chrisfcarroll/e38b9ffcc52fa9d4eb9ab73b13915f5a
Chris F 캐롤

34

Jeff Hillman의 게시물에서 두 번째 방법을 수정하려면 다음 중 하나를 수행하십시오.

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

또는

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

방금 전 ... "-Filter"옵션 대신 "-Query"를 사용하면 WmiObject가 반환되지 않으므로 "제거"방법이 없습니다.
Doug J. Huras

7

Win32_Product 클래스는 복구를 트리거하고 쿼리 최적화되지 않았으므로 권장하지 않는다는 것을 알았습니다. 출처

앱 guid를 알고 있다면 제거 할 스크립트가있는 Sitaram Pamarthi 에서이 게시물 을 찾았 습니다 . 또한 여기에서 정말 빠르게 앱을 검색 할 수있는 또 다른 스크립트를 제공 합니다 .

다음과 같이 사용하십시오.. \ 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"}
 }

7

이 게시물에 약간을 추가하려면 여러 서버에서 소프트웨어를 제거 할 수 있어야했습니다. 나는 Jeff의 대답을 사용하여 나를 이끌어 냈습니다.

먼저 서버 목록을 얻었고 AD 쿼리를 사용했지만 원하는 컴퓨터 이름 배열을 제공 할 수 있습니다.

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

그런 다음 gwmi 쿼리에 -computer 매개 변수를 추가하여 반복했습니다.

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

올바른 응용 프로그램을 제거했는지 확인하기 위해 IdentificationingNumber 속성을 이름 대신 일치시키는 데 사용했습니다.


간단하게 사랑스러운이 솔루션
Raffaeu

6
function Uninstall-App {
    Write-Output "Uninstalling $($args[0])"
    foreach($obj in Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") {
        $dname = $obj.GetValue("DisplayName")
        if ($dname -contains $args[0]) {
            $uninstString = $obj.GetValue("UninstallString")
            foreach ($line in $uninstString) {
                $found = $line -match '(\{.+\}).*'
                If ($found) {
                    $appid = $matches[1]
                    Write-Output $appid
                    start-process "msiexec.exe" -arg "/X $appid /qb" -Wait
                }
            }
        }
    }
}

이런 식으로 부르십시오 :

Uninstall-App "Autodesk Revit DB Link 2019"


3

나는 내 자신의 작은 기여를 할 것입니다. 같은 컴퓨터에서 패키지 목록을 제거해야했습니다. 이것은 내가 생각 해낸 스크립트입니다.

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

이것이 도움이 되길 바랍니다.

David Stetler는이 스크립트를 기반으로하기 때문에이 스크립트에 대한 크레딧을 빚지고 있습니다.


2

msiexec를 사용하는 PowerShell 스크립트는 다음과 같습니다.

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"

나는이 접근법을 다음 플래그 와 결합 했다. 어떤 이유로 이것은 나를 위해 다른 접근법보다 더 효과적이다.
David Rogers

1

Jeff Hillman의 답변을 바탕으로 :

다음 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

사용하다:

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 에서 모든 시스템을 검색하고 모든 시스템에서 여러 응용 프로그램을 제거하려고합니다.

IdentificationingNumber를 사용하여 David Stetlers 입력의 소프트웨어 원인을 검색했습니다.

검증되지 않은:

  1. 스크립트에서 함수 호출에 id를 추가하지 않고 대신 매개 변수 ID로 스크립트를 시작
  2. 함수에서 자동으로 검색 되지 않은 1 개 이상의 컴퓨터 이름 으로 스크립트 호출
  3. 파이프에서 데이터 검색
  4. IP 주소를 사용하여 시스템에 연결

그것이하지 않는 것 :

  1. 소프트웨어가 실제로 특정 시스템에서 발견 된 경우 정보를 제공하지 않습니다.
  2. 설치 제거 실패 또는 성공에 대한 정보는 제공하지 않습니다.

uninstall ()을 사용할 수 없습니다. NULL 값을 갖는 표현식에 대한 메소드 호출이 불가능하다는 오류가 발생했습니다. 대신 Remove-WmiObject를 사용했는데 같은 결과를 얻었습니다.

주의 : 컴퓨터 이름이 없으면 Active Directory의 모든 시스템에서 소프트웨어가 제거 됩니다.


0

대부분의 내 프로그램 에서이 게시물의 스크립트가 작업을 수행했습니다. 그러나 msiexec.exe 또는 Win32_Product 클래스를 사용하여 제거 할 수없는 레거시 프로그램에 직면해야했습니다. (어떤 이유로 인해 종료 0이 있지만 프로그램이 여전히 존재했습니다)

내 솔루션은 Win32_Process 클래스를 사용하는 것이 었습니다.

nickdnk 의 도움 으로이 명령은 설치 제거 exe 파일 경로를 얻는 것입니다.

64 비트 :

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

32 비트 :

 [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을 추가하면 작동 할 수 있다고 생각합니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.