How to Force-Remove / uninstall VMware Tools Using PowerShell


When the standard VMware Tools uninstaller fails, breaks mid-way, or leaves orphaned registry keys, this PowerShell script surgically removes every trace: registry entries, services, and filesystem directories. A reboot finishes the job.

Why the standard uninstaller sometimes fails

VMware Tools is generally well-behaved — but there are scenarios where the built-in Windows installer (MSI) gets stuck or leaves residual artifacts that block a clean reinstallation:

  • A failed or interrupted upgrade leaves the MSI in a broken state
  • The VM was cloned or snapshotted mid-installation
  • You’re migrating the guest OS from one hypervisor to another
  • The Add/Remove Programs entry is missing but services and files remain
  • You need to do a clean reinstall of a specific Tools version

In these cases, the automated script below is far more reliable than hunting through the registry manually.

Before you begin: Run this script only on a VM that is being migrated away from VMware, decommissioned, or undergoing a clean reinstall. Removing VMware Tools from a running VMware-hosted VM without reinstalling will disable mouse integration, shared clipboard, time synchronization, and balloon memory management.

Prerequisites

  • PowerShell 5.0 or higher (built into Windows Server 2016+; use Windows Management Framework for older OSes)
  • An elevated (Run as Administrator) PowerShell session — the script touches HKLM and HKCR registry hives
  • A snapshot or backup taken before running, in case a rollback is needed
  • The Remove_VMwareTools.ps1 script saved locally on the guest VM

The script

PowerShell — Remove_VMwareTools.ps1


# This script will manually rip out all VMware Tools registry entries and files
# Tested for Windows Server 2019, 2016, and 2012 R2+

# ── Step 1: Discover the VMware Tools installer IDs ──────────────────────────
function Get-VMwareToolsInstallerID {
foreach ($item in $(Get-ChildItem Registry::HKEY_CLASSES_ROOT\Installer\Products)) {
If ($item.GetValue('ProductName') -eq 'VMware Tools') {
return @{
reg_id = $item.PSChildName
msi_id = [Regex]::Match($item.GetValue('ProductIcon'), '(?<={)(.*?)(?=})') |
Select-Object -ExpandProperty Value
}
}
}
}

$vmware_tools_ids = Get-VMwareToolsInstallerID

# ── Step 2: Build the list of registry targets ───────────────────────────────
$reg_targets = @(
"Registry::HKEY_CLASSES_ROOT\Installer\Features\",
"Registry::HKEY_CLASSES_ROOT\Installer\Products\",
"HKLM:\SOFTWARE\Classes\Installer\Features\",
"HKLM:\SOFTWARE\Classes\Installer\Products\",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\"
)

$VMware_Tools_Directory = "C:\Program Files\VMware"
$VMware_Common_Directory = "C:\Program Files\Common Files\VMware"

$targets = @()
If ($vmware_tools_ids) {
foreach ($item in $reg_targets) {
$targets += $item + $vmware_tools_ids.reg_id
}
$targets += "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{$($vmware_tools_ids.msi_id)}"
}

# Legacy entries for Windows Server 2008 / 2012 (pre-10.0 kernel)
If ([Environment]::OSVersion.Version.Major -lt 10) {
$targets += "HKCR:\CLSID\{D86ADE52-C4D9-4B98-AA0D-9B0C7F1EBBC8}"
$targets += "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{9709436B-5A41-4946-8BE7-2AA433CAF108}"
$targets += "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{FE2F6A2C-196E-4210-9C04-2B1BC21F07EF}"
}

If (Test-Path "HKLM:\SOFTWARE\VMware, Inc.") { $targets += "HKLM:\SOFTWARE\VMware, Inc." }
If (Test-Path $VMware_Tools_Directory) { $targets += $VMware_Tools_Directory }
If (Test-Path $VMware_Common_Directory) { $targets += $VMware_Common_Directory }

# ── Step 3: Collect VMware services ──────────────────────────────────────────
$services = Get-Service -DisplayName "VMware*"
$services += Get-Service -DisplayName "GISvc"

# ── Step 4: Confirm and execute ───────────────────────────────────────────────
Write-Host "The following registry keys, filesystem folders, and services will be deleted:"
If (!$targets -and !$services) { Write-Host "Nothing to do!" }
Else {
$targets; $services
$user_confirmed = Read-Host "Continue (y/n)"
If ($user_confirmed -eq "y") {
$services | Stop-Service -Confirm:$false
If (Get-Command Remove-Service -errorAction SilentlyContinue) {
$services | Remove-Service -Confirm:$false
} Else {
foreach ($s in $services) { sc.exe DELETE $($s.Name) }
}
foreach ($item in $targets) {
If(Test-Path $item) { Remove-Item -Path $item -Recurse }
}
Write-Host "Done. Reboot to complete removal."
} Else { Write-Host "Failed to get user confirmation" }
}

What the script does — step by step

Phase 1 — Discover installer IDs

The function Get-VMwareToolsInstallerID walks HKCR\Installer\Products and finds the entry whose ProductName equals “VMware Tools”. It returns two values:

  • reg_id — the scrambled GUID used as the folder key across multiple registry hives
  • msi_id — the standard GUID extracted from the ProductIcon value, used in the Uninstall key

Phase 2 — Build the target list

Using the discovered IDs, the script compiles a list of every registry path that holds VMware installer metadata:

Registry hivePurpose
HKCR\Installer\Features\{id}Feature advertisement records
HKCR\Installer\Products\{id}Core product registration
HKLM\SOFTWARE\Classes\Installer\Features\{id}WOW64 mirror of Features
HKLM\SOFTWARE\Classes\Installer\Products\{id}WOW64 mirror of Products
HKLM\…\UserData\S-1-5-18\Products\{id}Per-machine install data (SYSTEM account)
HKLM\…\Uninstall\{msi_id}Add/Remove Programs entry
HKLM\SOFTWARE\VMware, Inc.VMware application settings

It also adds two filesystem directories to the list: C:\Program Files\VMware and C:\Program Files\Common Files\VMware (the latter can hold up to ~500 MB of shared libraries).

For guests running Windows Server 2008 or 2012 (kernel version < 10), three additional hard-coded legacy GUIDs are appended to cover CLSIDs that don’t exist on newer OSes.

Phase 3 — Enumerate VMware services

The script queries the Service Control Manager for all services whose display name starts with “VMware”, plus GISvc (the VMware Guest Introspection service), which uses a different naming convention.

Phase 4 — Confirm and execute

Before touching anything, the script prints the full target list and asks for explicit confirmation (y). On approval it:

  1. Stops all VMware services via Stop-Service
  2. Removes services — using Remove-Service on PowerShell 6+, or falling back to sc.exe DELETE on older versions
  3. Iterates every target and calls Remove-Item -Recurse if the path exists
  4. Prompts the operator to reboot to flush any in-memory driver handles

How to run it

  • Copy Remove_VMwareTools.ps1 to the guest VM (e.g. C:\Temp\)
  • Open PowerShell as Administrator
  • If execution policy blocks scripts, temporarily unblock: Set-ExecutionPolicy Bypass -Scope Process
  • Run: .\Remove_VMwareTools.ps1
  • Review the list of targets printed on screen, type y and press Enter to confirm
  • Reboot the VM when prompted

After reboot: Confirm removal by checking Services.msc (no VMware entries) and C:\Program Files\VMware (directory should be gone). You can now perform a clean installation of VMware Tools or migrate the VM to a different hypervisor without conflicts.

Frequently asked questions

What if the script reports “Nothing to do”?

VMware Tools is either not installed, or was already cleanly removed. No action is needed.

Will this work if VMware Tools is actively running?

Yes — the script stops services before deletion. You do not need to stop them manually first.

Is this safe to run remotely via PSRemoting or RDP?

Yes. The only dependency is an elevated PowerShell session. Run it via Invoke-Command or a remote desktop session — both work fine.

What about Windows 10 / Windows 11 desktop guests?

The script targets Windows Server 2008–2019 and was not tested on desktop editions. The registry paths are the same, but desktop VMs are out of scope for this guide.

Leave a Reply

Your email address will not be published. Required fields are marked *