Last active
July 1, 2025 14:36
-
-
Save KGHague/2c562ee88492c1c0c0eac1b3ae0fecd8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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-WmiObject -Query "SELECT * FROM Win32_Product WHERE Name = 'VMware Tools'" | |
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" | Select-Object -ExpandProperty LocalPackage | |
if ($localPackage) { | |
Write-Output "VMware Tools MSI path: $localPackage" | |
# 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) | |
[System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($view) | |
# Commit the changes and close the database | |
$database.GetType().InvokeMember("Commit", "InvokeMethod", $null, $database, $null) | |
[System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($database) | |
# Uninstall VMware Tools | |
Start-Process msiexec.exe -ArgumentList "/x `"$localPackage`" /qn" -Wait | |
} else { | |
Write-Output "LocalPackage path not found in the registry." | |
} | |
} 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
@DanAvni Thanks!