Có cách nào đơn giản để nối vào chức năng ' Thêm hoặc xóa chương trình ' tiêu chuẩn bằng PowerShell để gỡ cài đặt ứng dụng hiện có không? Hoặc để kiểm tra nếu ứng dụng được cài đặt?
Có cách nào đơn giản để nối vào chức năng ' Thêm hoặc xóa chương trình ' tiêu chuẩn bằng PowerShell để gỡ cài đặt ứng dụng hiện có không? Hoặc để kiểm tra nếu ứng dụng được cài đặt?
Câu trả lời:
$app = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match "Software Name"
}
$app.Uninstall()
Chỉnh sửa: Rob tìm thấy một cách khác để làm điều đó với tham số Bộ lọc:
$app = Get-WmiObject -Class Win32_Product `
-Filter "Name = 'Software Name'"
(gwmi Win32_Product | ? Name -eq "Software").uninstall()
Một ít mã golf.
EDIT: Trong những năm qua, câu trả lời này đã nhận được khá nhiều sự ủng hộ. Tôi muốn thêm một số ý kiến. Tôi chưa sử dụng PowerShell, nhưng tôi nhớ quan sát một số vấn đề:
-First 1
vậy nhưng tôi không chắc. Hãy chỉnh sửa.Sử dụng đối tượng WMI sẽ mất mãi mãi. Điều này rất nhanh nếu bạn chỉ biết tên chương trình bạn muốn gỡ cài đặt.
$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*"
vì phiên bản có tên và nó thay đổi, nhưng dường như nó không tìm thấy chương trình. Có ý kiến gì không?
Để sửa phương thức thứ hai trong bài của Jeff Hillman, bạn có thể thực hiện:
$app = Get-WmiObject
-Query "SELECT * FROM Win32_Product WHERE Name = 'Software Name'"
Hoặc là
$app = Get-WmiObject -Class Win32_Product `
-Filter "Name = 'Software Name'"
Tôi phát hiện ra rằng lớp Win32_ Productt không được khuyến nghị vì nó kích hoạt sửa chữa và không được tối ưu hóa truy vấn. Nguồn
Tôi tìm thấy bài đăng này từ Sitaram Pamarthi với một đoạn script để gỡ cài đặt nếu bạn biết hướng dẫn ứng dụng. Ông cũng cung cấp một kịch bản khác để tìm kiếm các ứng dụng thực sự nhanh chóng ở đây .
Sử dụng như thế này :. \ 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"}
}
Để thêm một chút vào bài đăng này, tôi cần có khả năng xóa phần mềm khỏi nhiều Máy chủ. Tôi đã sử dụng câu trả lời của Jeff để dẫn tôi đến điều này:
Đầu tiên tôi có một danh sách các máy chủ, tôi đã sử dụng truy vấn AD , nhưng bạn có thể cung cấp mảng tên máy tính theo cách bạn muốn:
$computers = @("computer1", "computer2", "computer3")
Sau đó, tôi lặp qua chúng, thêm tham số -computer vào truy vấn gwmi:
foreach($server in $computers){
$app = Get-WmiObject -Class Win32_Product -computer $server | Where-Object {
$_.IdentifyingNumber -match "5A5F312145AE-0252130-432C34-9D89-1"
}
$app.Uninstall()
}
Tôi đã sử dụng thuộc tính IdentifyingNumber để khớp với thay vì tên, chỉ để chắc chắn rằng tôi đang gỡ cài đặt ứng dụng chính xác.
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
}
}
}
}
}
Gọi nó theo cách này:
Uninstall-App "Autodesk Revit DB Link 2019"
Một dòng mã:
get-package *notepad* |% { & $_.Meta.Attributes["UninstallString"]}
Tôi sẽ đóng góp nhỏ của riêng tôi. Tôi cần phải xóa một danh sách các gói từ cùng một máy tính. Đây là kịch bản tôi nghĩ ra.
$packages = @("package1", "package2", "package3")
foreach($package in $packages){
$app = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match "$package"
}
$app.Uninstall()
}
Tôi hy vọng điều này chứng tỏ là hữu ích.
Lưu ý rằng tôi nợ David Stetler tín dụng cho kịch bản này vì nó dựa trên kịch bản của anh ấy.
Đây là tập lệnh PowerShell sử dụng 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"
Dựa trên câu trả lời của Jeff Hillman:
Đây là một chức năng bạn chỉ có thể thêm vào profile.ps1
hoặc xác định trong phiên PowerShell hiện tại:
# 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 + "'")
}
}
Giả sử bạn muốn gỡ cài đặt Notepad ++ . Chỉ cần nhập cái này vào PowerShell:
> uninstall("notepad++")
Chỉ cần lưu ý rằng Get-WmiObject
có thể mất một thời gian, vì vậy hãy kiên nhẫn!
Sử dụng:
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}"
Nó chưa được thử nghiệm đầy đủ, nhưng nó chạy dưới PowerShell 4.
Tôi đã chạy tệp PS1 như được thấy ở đây. Để nó truy xuất tất cả các Hệ thống từ AD và cố gắng gỡ cài đặt nhiều ứng dụng trên tất cả các hệ thống.
Tôi đã sử dụng Mã xác định để tìm kiếm nguyên nhân Phần mềm của đầu vào David Stetlers.
Không được kiểm tra:
Những gì nó không:
Tôi không thể sử dụng gỡ cài đặt (). Cố gắng rằng tôi đã gặp lỗi khi nói với tôi rằng việc gọi một phương thức cho một biểu thức có giá trị NULL là không thể. Thay vào đó, tôi đã sử dụng Remove-WmiObject, có vẻ như hoàn thành tương tự.
THẬN TRỌNG : Không có tên máy tính được cung cấp, nó sẽ xóa phần mềm khỏi TẤT CẢ các hệ thống trong Active Directory.
Đối với hầu hết các chương trình của tôi, các kịch bản trong Bài đăng này đã thực hiện công việc. Nhưng tôi đã phải đối mặt với một chương trình cũ mà tôi không thể xóa bằng lớp msiexec.exe hoặc Win32_ Productt. (từ một số lý do tôi đã thoát 0 nhưng chương trình vẫn ở đó)
Giải pháp của tôi là sử dụng lớp Win32_Process:
với sự trợ giúp từ nickdnk , lệnh này là để lấy đường dẫn tệp exe gỡ cài đặt:
64 bit:
[array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString
32 bit:
[array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString
bạn sẽ phải xóa chuỗi kết quả:
$uninstallPath = $unInstallPathReg[0].UninstallString
$uninstallPath = $uninstallPath -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstallPath = $uninstallPath .Trim()
Bây giờ khi bạn có chương trình liên quan gỡ cài đặt đường dẫn tệp exe, bạn có thể sử dụng lệnh này:
$uninstallResult = (Get-WMIObject -List -Verbose | Where-Object {$_.Name -eq "Win32_Process"}).InvokeMethod("Create","$unInstallPath")
$ UninstallResult - sẽ có mã thoát. 0 là thành công
các lệnh trên cũng có thể chạy từ xa - Tôi đã thực hiện bằng lệnh invoke nhưng tôi tin rằng việc thêm đối số -computername có thể hoạt động