답변:
$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'"
(gwmi Win32_Product | ? Name -eq "Software").uninstall()
작은 코드 골프.
편집 : 몇 년 동안이 대답은 꽤 많은 공감을 얻었습니다. 의견을 추가하고 싶습니다. 이후 PowerShell을 사용하지 않았지만 몇 가지 문제를 관찰 한 것을 기억합니다.
-First 1
확실하지 않습니다. 자유롭게 편집하십시오.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}
-like "appNam*"
버전이 이름에 있고 버전이 바뀌기 때문에 이것을 사용하려고 하지만 프로그램을 찾지 못하는 것 같습니다. 어떤 아이디어?
Jeff Hillman의 게시물에서 두 번째 방법을 수정하려면 다음 중 하나를 수행하십시오.
$app = Get-WmiObject
-Query "SELECT * FROM Win32_Product WHERE Name = 'Software Name'"
또는
$app = Get-WmiObject -Class Win32_Product `
-Filter "Name = 'Software Name'"
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"}
}
이 게시물에 약간을 추가하려면 여러 서버에서 소프트웨어를 제거 할 수 있어야했습니다. 나는 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 속성을 이름 대신 일치시키는 데 사용했습니다.
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"
한 줄의 코드 :
get-package *notepad* |% { & $_.Meta.Attributes["UninstallString"]}
나는 내 자신의 작은 기여를 할 것입니다. 같은 컴퓨터에서 패키지 목록을 제거해야했습니다. 이것은 내가 생각 해낸 스크립트입니다.
$packages = @("package1", "package2", "package3")
foreach($package in $packages){
$app = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match "$package"
}
$app.Uninstall()
}
이것이 도움이 되길 바랍니다.
David Stetler는이 스크립트를 기반으로하기 때문에이 스크립트에 대한 크레딧을 빚지고 있습니다.
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"
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
어느 정도 시간이 걸릴 수 있으므로, 환자가 될 수 있습니다!
사용하다:
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 입력의 소프트웨어 원인을 검색했습니다.
검증되지 않은:
그것이하지 않는 것 :
uninstall ()을 사용할 수 없습니다. NULL 값을 갖는 표현식에 대한 메소드 호출이 불가능하다는 오류가 발생했습니다. 대신 Remove-WmiObject를 사용했는데 같은 결과를 얻었습니다.
주의 : 컴퓨터 이름이 없으면 Active Directory의 모든 시스템에서 소프트웨어가 제거 됩니다.
대부분의 내 프로그램 에서이 게시물의 스크립트가 작업을 수행했습니다. 그러나 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을 추가하면 작동 할 수 있다고 생각합니다