You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell Invoke-Command批量卸载软件效率优化:如何实现多主机同时执行?

Question: Parallelizing Application Uninstallation Across Multiple Computers in PowerShell

I've written a PowerShell script that reads a list of target computers from a text file and uninstalls an application on each machine. The script works, but each uninstall takes 2-3 minutes, so running it sequentially is slow. I want to know if I can run the uninstall on all target computers simultaneously to improve efficiency.

Here's my current script:

$computers = Get-Content C:\Computernames.txt
foreach($Computer in $computers){
    Invoke-Command -ComputerName $Computer -ScriptBlock{
        $application = Get-WmiObject -Class Win32_Product -Filter "Name LIKE '%Appname%'"
        #uninstall the app if it exists
        if($application){
            $application.Uninstall()
            Write-Output "Application uninstalled successfully.."
        } else{
            Write-Output "Application not found.."
        }
    }
}

Can I avoid the loop and use Invoke-Command -ComputerName $Computers directly to run the uninstall on all machines at the same time?


Answer

Absolutely! Your intuition is spot-on — Invoke-Command natively supports parallel execution when you pass an array of computer names directly to the -ComputerName parameter. By default, it runs against up to 32 computers at once (you can tweak this with the -ThrottleLimit parameter if needed), which will slash your total runtime compared to the sequential loop you’re using now.

Here’s the modified script to run in parallel:

$computers = Get-Content C:\Computernames.txt
Invoke-Command -ComputerName $computers -ScriptBlock {
    # Note: Win32_Product has hidden overhead (triggers MSI consistency checks)
    # See the note below for a faster alternative
    $application = Get-WmiObject -Class Win32_Product -Filter "Name LIKE '%Appname%'"
    if ($application) {
        $uninstallResult = $application.Uninstall()
        # Verify success using the MSI return code (0 = successful)
        if ($uninstallResult.ReturnValue -eq 0) {
            Write-Output "[$env:COMPUTERNAME] Application uninstalled successfully."
        } else {
            Write-Output "[$env:COMPUTERNAME] Uninstall failed with code: $($uninstallResult.ReturnValue)"
        }
    } else {
        Write-Output "[$env:COMPUTERNAME] Application not found."
    }
}

Key optimizations and tips:

  • Ditch Win32_Product for speed: This class forces a full check of all installed MSI packages every time it’s called, which adds unnecessary delay. A better approach is to query the Windows registry directly:
    # Query 64-bit application registry path (adjust for 32-bit if needed)
    $app = Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" | 
           Where-Object { $_.DisplayName -like '%Appname%' }
    if ($app) {
        # Add silent uninstall parameters (adjust based on your app's requirements)
        $uninstallCommand = $app.UninstallString.Replace('"', '') + " /qn"
        Start-Process -FilePath "msiexec.exe" -ArgumentList $uninstallCommand -Wait -NoNewWindow
        Write-Output "[$env:COMPUTERNAME] Uncompleted successfully."
    }
    
  • Adjust parallelism limit: If you have dozens of machines and your network can handle it, add -ThrottleLimit 64 to Invoke-Command to increase the number of simultaneous connections.
  • Handle errors gracefully: Add -ErrorAction SilentlyContinue to skip unreachable machines, or wrap the logic in a try/catch block to log failures explicitly. You can also use -AsJob to run the uninstalls as background jobs if you need to work on other tasks while they run.

This parallel approach will run the uninstallation on all your target machines at the same time, cutting your total wait time from hours to just a few minutes.

内容的提问来源于stack exchange,提问作者MF-

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 04:57:45