Skip to content

Instantly share code, notes, and snippets.

@Jason-Clark-FG
Last active November 26, 2025 15:31
Show Gist options
  • Select an option

  • Save Jason-Clark-FG/68e23b534f5be4e3f3b43f3bd37f1d65 to your computer and use it in GitHub Desktop.

Select an option

Save Jason-Clark-FG/68e23b534f5be4e3f3b43f3bd37f1d65 to your computer and use it in GitHub Desktop.
A quick update to the gist at https://gist.github.com/KGHague/2c562ee88492c1c0c0eac1b3ae0fecd8 to incorporate the additional suggestions
<#
.SYNOPSIS
Uninstalls VMware Tools using the MSI installer method.
.DESCRIPTION
This script modifies the VMware Tools MSI database to bypass environment checks
that prevent uninstallation on non-VMware systems, then performs an uninstall.
.PARAMETER Uninstall
Actually perform the uninstall. Without this switch, the script runs in dry-run mode.
.PARAMETER Force
Bypass the confirmation prompt and proceed with uninstallation automatically.
.EXAMPLE
.\Uninstall-VMwareTools.ps1
Dry run mode - shows what would be done without actually uninstalling.
.EXAMPLE
.\Uninstall-VMwareTools.ps1 -Uninstall
Prompts for confirmation before uninstalling VMware Tools.
.EXAMPLE
.\Uninstall-VMwareTools.ps1 -Uninstall -Force
Uninstalls VMware Tools without prompting for confirmation.
.LINK
https://gist.github.com/KGHague/2c562ee88492c1c0c0eac1b3ae0fecd8
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$false)]
[switch]$Uninstall = $false,
[Parameter(Mandatory=$false)]
[switch]$Force
)
#Requires -RunAsAdministrator
function ConvertTo-PackedGuid {
<#
.SYNOPSIS
https://gist.github.com/MyITGuy/d3e039c5ec7865edefc157fcd625a20a
Converts a GUID string into a packed globally unique identifier (GUID) string.
.DESCRIPTION
Takes a GUID string and breaks it into 6 parts. It then loops through the first five parts and reversing the order. It loops through the sixth part and reversing the order of every 2 characters. It then joins the parts back together and returns a packed GUID string.
.EXAMPLE
ConvertTo-PackedGuid -Guid '{7C6F0282-3DCD-4A80-95AC-BB298E821C44}'
The output of this example would be: 2820F6C7DCD308A459CABB92E828C144
.PARAMETER Guid
A globally unique identifier (GUID).
#>
[CmdletBinding()]
[OutputType([System.String])]
param (
[Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, Mandatory)]
[ValidateScript( { [System.Guid]::Parse($_) -is [System.Guid] })]
[System.Guid]$Guid
)
process {
Write-Verbose "Guid: $($Guid)"
$GuidString = $Guid.ToString('N')
Write-Verbose "GuidString: $($GuidString)"
$Indexes = [ordered]@{
0 = 8
8 = 4
12 = 4
16 = 2
18 = 2
20 = 12
}
$PackedGuid = ''
foreach ($index in $Indexes.GetEnumerator()) {
$Substring = $GuidString.Substring($index.Key, $index.Value)
Write-Verbose "Substring: $($Substring)"
switch ($index.Key) {
20 {
$parts = $Substring -split '(.{2})' | Where-Object { $_ }
foreach ($part In $parts) {
$part = $part -split '(.{1})'
Write-Verbose "Part: $($part)"
[System.Array]::Reverse($part)
Write-Verbose "Reversed: $($part)"
$PackedGuid += $part -join ''
}
}
default {
$part = $Substring.ToCharArray()
Write-Verbose "Part: $($part)"
[System.Array]::Reverse($part)
Write-Verbose "Reversed: $($part)"
$PackedGuid += $part -join ''
}
}
}
[System.Guid]::Parse($PackedGuid).ToString('N').ToUpper()
}
}
# Create an instance of the WindowsInstaller.Installer object
$installer = New-Object -ComObject WindowsInstaller.Installer
# Get the list of installed programs and find the VMware Tools entry
$vmwareTools = Get-CimInstance -Query "SELECT * FROM Win32_Product WHERE Name = 'VMware Tools'" -ErrorAction SilentlyContinue
if ($vmwareTools) {
# Extract the identifying number (GUID)
[guid]$guid = $vmwareTools.IdentifyingNumber
# Convert the guid to a packed guid
[string]$packedguid = ConvertTo-PackedGuid $guid
# Get the LocalPackage path from the registry
$localPackage = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\${packedguid}\InstallProperties" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty LocalPackage
if ($localPackage) {
Write-Host "VMware Tools MSI path: $localPackage" -ForegroundColor Yellow
# Open the MSI database in read-write mode
$database = $installer.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $null, $installer, @("${localPackage}", 2))
# Remove the VM_LogStart and VM_CheckRequirements rows in the CustomAction table
# VM_CheckRequirements added as recommended by @DanAvni
$query = "DELETE FROM CustomAction WHERE Action='VM_LogStart' OR Action='VM_CheckRequirements'"
$view = $database.GetType().InvokeMember("OpenView", "InvokeMethod", $null, $database, @($query))
$view.GetType().InvokeMember("Execute", "InvokeMethod", $null, $view, $null)
$view.GetType().InvokeMember("Close", "InvokeMethod", $null, $view, $null)
[void][System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($view)
# Commit the changes and close the database
$database.GetType().InvokeMember("Commit", "InvokeMethod", $null, $database, $null)
[void][System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($database)
Write-Host "MSI database modified successfully." -ForegroundColor Green
# Uninstall VMware Tools
if ($Uninstall) {
# Check if Force parameter is used or get user confirmation
if ($Force) {
$user_confirmed = "y"
Write-Host "Force parameter specified - proceeding with uninstallation..." -ForegroundColor Yellow
}
else {
$user_confirmed = Read-Host "Proceed with uninstallation? (y/n)"
}
if ($user_confirmed -eq "y") {
Write-Host "Uninstalling VMware Tools..." -ForegroundColor Yellow
Start-Process msiexec.exe -ArgumentList "/x `"${localPackage}`" /qn /norestart" -Wait
Write-Host "Uninstallation completed." -ForegroundColor Green
}
else {
Write-Host "Uninstallation cancelled by user." -ForegroundColor Yellow
}
}
else {
Write-Host "Dry run mode. To actually uninstall VMware Tools, run the script with the -Uninstall switch." -ForegroundColor Cyan
return
}
}
else {
Write-Host "LocalPackage path not found in the registry." -ForegroundColor Red
}
}
else {
Write-Output "VMware Tools is not installed."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment