-
Star
(130)
You must be signed in to star a gist -
Fork
(31)
You must be signed in to fork a gist
-
-
Save broestls/f872872a00acee2fca02017160840624 to your computer and use it in GitHub Desktop.
| # This script will manually rip out all VMware Tools registry entries and files for Windows 2008-2019 | |
| # Tested for 2019, 2016, and probably works on 2012 R2 after the 2016 fixes. | |
| # This function pulls out the common ID used for most of the VMware registry entries along with the ID | |
| # associated with the MSI for VMware Tools. | |
| 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 | |
| # Targets we can hit with the common registry ID from $vmware_tools_ids.reg_id | |
| $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" | |
| # Create an empty array to hold all the uninstallation targets and compose the entries into the target array | |
| $targets = @() | |
| If ($vmware_tools_ids) { | |
| foreach ($item in $reg_targets) { | |
| $targets += $item + $vmware_tools_ids.reg_id | |
| } | |
| # Add the MSI installer ID regkey | |
| $targets += "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{$($vmware_tools_ids.msi_id)}" | |
| } | |
| # This is a bit of a shotgun approach, but if we are at a version less than 2016, add the Uninstaller entries we don't | |
| # try to automatically determine. | |
| 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}" | |
| } | |
| # Add the VMware, Inc regkey | |
| If (Test-Path "HKLM:\SOFTWARE\VMware, Inc.") { | |
| $targets += "HKLM:\SOFTWARE\VMware, Inc." | |
| } | |
| # Add the VMware Tools directory | |
| If(Test-Path $VMware_Tools_Directory) { | |
| $targets += $VMware_Tools_Directory | |
| } | |
| # Thanks to @Gadgetgeek2000 for pointing out that the script leaves some 500mb of extra artifacts on disk. | |
| # This blob removes those. | |
| If(Test-Path $VMware_Common_Directory) { | |
| $targets += $VMware_Common_Directory | |
| } | |
| # Create a list of services to stop and remove | |
| $services = Get-Service -DisplayName "VMware*" | |
| $services += Get-Service -DisplayName "GISvc" | |
| # Warn the user about what is about to happen | |
| # Takes only y for an answer, bails otherwise. | |
| 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") { | |
| # Stop all running VMware Services | |
| $services | Stop-Service -Confirm:$false | |
| # Cover for Remove-Service not existing in PowerShell versions < 6.0 | |
| If (Get-Command Remove-Service -errorAction SilentlyContinue) { | |
| $services | Remove-Service -Confirm:$false | |
| } | |
| Else { | |
| foreach ($s in $services) { | |
| sc.exe DELETE $($s.Name) | |
| } | |
| } | |
| # Remove all the files that are listed in $targets | |
| 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" | |
| } | |
| } |
:( That's frustrating! I wish you luck! :-)
@SDC-SYSAD no luck, crashes out just as @Car10sH says. It seems to be a problem with that particular version. 12.5.4.249629. I am going to have to try the script.
@ItMan47 - As suggested by mateuszdrab, it is worth you running the msiexec uninstall process with verbose logging enabled, as this will help you to identify what is causing the uninstall process to fail.
- From elevated Command Prompt, navigate to C:\Windows\Installer
- Locate the VMware Tools MSI (usually has a hexadecimal value for a filename)
- Run: msiexec /x <msifilename.msi> or {product_code} /L*v C:\Temp<logname.log>
- Once the installer fails, open the log file and search for "1603" - this should give you a pointer towards the problem (that's how I found the reference to the CustomAction: VM_UninstGHIRestGuestHandle.869A7E00_8665_0000_83A8_EF0F76CF0001)
You can then remove references to whichever CustomAction it shows from the MSI via Orca.
Hope this helps!
@Car10sH Interesting, I thought I had removed all instances of VM_CheckRequirements with Orca but I am seeing this
MSI (s) (B4:C4) [16:54:03:068]: Doing action: VM_CheckRequirements
Action ended 16:54:03: LaunchConditions. Return value 1.
MSI (s) (B4:B0) [16:54:03:083]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIAF20.tmp, Entrypoint: VMCheckRequirements
Action start 16:54:03: VM_CheckRequirements.
CustomAction VM_CheckRequirements returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
MSI (s) (B4:C4) [16:54:03:630]: Doing action: VM_SendMsiLogToHostOnError
Action ended 16:54:03: VM_CheckRequirements. Return value 3.
Double checking the MSI now.
CTRL+F VM_CheckRequirements returns nothing found. I am stumped.
did find this also just after that 1603
MSI (s) (B4:98) [16:54:03:646]: Invoking remote custom action. DLL: C:\Windows\Installer\MSIB154.tmp, Entrypoint: VMSendMsiLogToHost
Action start 16:54:03: VM_SendMsiLogToHostOnError.
Action ended 16:54:03: VM_SendMsiLogToHostOnError. Return value 1.
Action ended 16:54:03: INSTALL. Return value 3.
Clearly that isn't going to work either.
@ItMan47 Are you modifying the relevant MSI held in C:\Windows\Installer via Orca? I found it only works if you update that one (make a copy first just in case, give it a .bak extension or something), as that is what the uninstall process calls.
@Car10sH kind of, I copied this out of the folder on to another machine, edited it with orca and saved it, then copied the edited file I saved back over to the original folder.
@Car10sH that path you gave me C:\Windows\Installer is that correct? The VM is running a Server OS not a desktop OS. I am finding the file is in C:\Program Files\Common Files\VMware\InstallerCache. Just running a search for the Product Code to see if it is anywhere else on the machine. I found a folder with the product code in the location you gave but it only has the Icon file in it. I am going to copy the modified msi in there and see if it will execute.
No joy, calling it a night, hit this again on Monday, thanks to @Car10sH and @SDC-SYSAD
https://help.zerto.com/bundle/z-kb-articles-zertokbs/page/4336.html
_When you try to install VMware tools on a VM that's running on Hyper-V hypervisor, the installation fails.
The reason is that the VMware Tools installer checks for an underlying VMware product hosting the VM. If it isn't found, the installer won't continue. VMware tools can't be installed on a VM that's running on Hyper-V hypervisor.
The correct procedure to install the VMware tools on a VM that's running on Hyper-V is to failover the VM to the VMware environment, install the VMware tools, and then failback.
Workaround
If you want to work around the correct procedure, you can download a VMware Tools MSI and remove the table row that runs this check. If you currently have an MSI for VMware Tools, open it for editing (ORCA is a commonly used tool for this - ORCA.EXE), and remove the row “VM_CheckRequirements” from the sequence table “InstallUISequence.”_
Having removed every instance I could find with Orca I suspect the VMCheckRequirements has been hard coded into the version I have at low level. It was one of the latest released by VMWare (its a patch for a CVE) and this is long after Broadcom's takeover. That would explain the log file still calling VMCheckRequirements even after applying the workaround. This would be designed to defeat the workaround and may have broken the uninstall too.
@ItMan47 Yes, C:\Windows\Installer is a common path used by both server and desktop, it is not unique to desktop. The folder will likely be hidden if you are trying to view it through Windows Explorer. This folder will hold the MSI that is called when running uninstall from GUI. The MSI in the folder will be named with a random hexadecimal string. This used to be named the same across all servers, but I have found with this version it is randomly named - in my case it is was 5554.msi, but was called 5EF6A4.msi on another server. The easiest way to identify the right MSI is to check the file size - for this specific version (for me at least), the file was 71,086,080 bytes in length. Once you've copied the modified MSI to this location with the same name, I would suggest running the uninstall process directly from an elevated command prompt from this location, much like you did when generating the verbose log file, so msiexec /x <filename.msi>. That has worked for me every single time, across multiple servers.
Hi @Car10sH thanks for the detailed update, you are correct in server 2022 that path is superhidden, only way I found to access it is to create a short cut to the folder or to type it in by hand. I will give this a go on Monday. Thank you very much.
Hi @Car10sH and @SDC-SYSAD
Success, or at least partially, see below.
Thank you for the detailed instructions on what rows to drop in Orca and where to find the actual .msi used by the msixexc uninstall routine and how to identify that file. Using it I managed to find mine and edit with Orca. It ran fine first time from the standard Settings > Apps > Installed Apps method.
I may have found a possible alternative method of identifying the randomly named .msi in the folder
In HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\ Products search for the string VMware Tools. It should bring you up long product ID key and in the sub key InstallProperties the LocalPackage will give you the actual file name
I believe the S-1-5-18 user is Adminstrator and it seems the path and product identifer is consistent across different servers. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\669464E1AC9BA434A953ABFDCB7CFADA
Given that tracking down the offending .msi file name will be a lot easier than looking for the exact file size I hope.
That said if you open Device manager in the VM after migration to Hyper-V that despite running the VMware Tools uninstall and a reboot you find (if you turn on "show hidden devices") the vmxnet3 adaptors are still present along with a few other VMware devices as well. QED it is not a clean uninstall of associated settings in Device Manager and other places too.
That the old NICs are still seen by the OS is shown by the fact that you cannot set the same Static IP as you had before without the warning this IP is in use by another adaptor. Luckily it does let you unassign the IP from the old vmxnet to the new Hyper-V adaptor. It was that warning that sent me looking in the device manager in the first place. Couldnt see any other NIC so turned on show hidden and voila there they were along with a other VMware only devices too. :(
I will continue to experiment but I think the manual tidy up in device manager after uninstalling the tools is going to be necessary no matter what.
Thanks again :)
I will continue to experiment but I think the manual tidy up in device manager after uninstalling the tools is going to be necessary no matter what.
I wouldn't bother. It will never be a perfectly clean after a cross hypervisor migration, if that's a requirement then you should re-install the OS from scratch and migrate data to the new VM
Hi @zxcvxzcv-johndoe I am in testing mode for an upcoming migration from ESXi. You are right; a completely clean device manager is not possible. However, what is concerning me (and hence the experimentation and documentation) is the change in Interface ID number caused by the new NIC(s) being installed alongside the existing legacy NIC(s). This has implications I did not expect.
Background: Using Veeam's Instant Recovery option to migrate from earlier versions of ESXi creates a Generation 1 Hyper-V VM. The migrated server has the correct number of NIC installed and still has the correct IP, Subnet Mask and Gateway (or no gateway if a secondary NIC) asssigned. It does not however work as expected. I found this out by accident. I figured it was worth doing two steps at once i.e. migration from ESXi then upgrade from Gen1 to Gen2 to remove any uncecessary legacy Hyper-V VM devices i.e. the Floppy, Com Ports and the legacy virtual IDE adaptor for Boot Device.
To convert the Gen 1 VM to a Gen 2 VM you copy the boot disk for backup reasons boot to install CD on the Gen1 and choose recovery and command line, run mbr2gpt on the boot disk and shut down, detach the now GPT disk from the VM and if you want to keep the old VM for fall back reattach the backup copy of the old MBR disk to the IDE. Now create a new Gen 2 VM with no disks attached, configure as required and attach the converted GPT disk to the new VM.
Doing this works but you loose the NIC customisations and now have a pair of NIC in DHCP. Attempting to reconfigure those to static IP is what lead me to find the hidden legacy vmxnet3 adaptors. Investigating the routing table showed the static routes gone in the new Gen 2. I fired up the old Gen 1 and found the static route had been deleted by the initial migration from ESXi not by the conversion to Gen 2.
Root Cause? This installation of the Hyper-V NICs alongside the legacy NICs changes the Interface ID as shown in Route Print. This change in IF ID breaks the persistenent static route in Windows because the persistent static routes are bound to the Interface by the ID number on creation.
@SDC-SYSAD

Still stuck with the above.
Didn't work. I am going to try without the modification suggested by @Car10sH and see what happens