Windows Registry Access from vRealize Orchestrator

< Back

Quick notes on how to access and manipulate and registry of a Windows VM from vRealize Orchestrator. This is a bit messy and I plan to come back later and rewrite this!

I remember this thing.

If you, like me, don't know much about Windows, the image above has some terminology regarding the registry. You can think of Keys as folders which contain Values or other Keys. Values have a Name, a Type, and Data. A Key which is contained by another Key is also referred to as a Subkey. Values do not need to have Data. All Keys contain a Value called Default. The top level Keys are also called Root Keys. Microsoft has a real write up here but this should get you through this blog post.

PREREQUISITES

SETUP

Create a new VcVirtualMachine instance referring to the Windows machine you want. Here’s a simple way to do this by looking the machine up by name:


            var vmList = VcPlugin.getAllVirtualMachines(null, "ws2019");
            var vm = vmList[0];
        

Create a new VcNamePasswordAuthentication with the credentials for a user which has the permissions to do what you want to the registry:


            var guestAuth = new VcNamePasswordAuthentication(false, "administrator", “P@ssw0rd!”);
        

I’ll show below what kind of errors result if the user specified doesn’t have enough permissions. The first boolean value in this setup determines if the session is interactive - in our case we don’t need this.

Create a new var to be a reference to the VM's guestWindowsRegistryManager:


            var registryManager = vm.sdkConnection.guestOperationsManager.guestWindowsRegistryManager;
        

We can now use our registryManager and its functions to manipulate the registry. All functions provided by the registry manager require the VcVirtualMachine and VcNamePasswordAuthentication objects we created as parameters.

LISTING KEYS

The registry manager's listRegistryKeysInGuest will list all the Subkeys of a given Key. However, we have to define the Key in which to enumerate Subkeys as a VcGuestRegKeyNameSpec object. The two values you need to set are the registryPath and wowBitness, both as strings. They can also be provided as parameters to the constructor:


            var guestRegKeyNameSpec = new VcGuestRegKeyNameSpec("HKLM", "WOWNative");
        

The registryPath is the full path to the key you want to enumerate subkeys in. This can be a root key like HKEY_LOCAL_MACHINE or any of the other root keys, or a subkey. It seems like these root keys can normally be abbreviated (HKEY_CURRENT_USER = HKCU, HKEY_CURRENT_CONFIG = HKCC, etc) but the only one that seems to actually work via this Plugin is HKEY_LOCAL_MACHINE’s abbreviation HKLM. Additionally, you must escape the \ character in the registry path (with another \), for example “HKEY_LOCAL_MACHINE\\SOFTWARE” rather than “HKEY_LOCAL_MACHINE\SOFTWARE”.

The three allowed values for the wowBitness are WOW32, WOW64 and WOWNative. See Microsoft's documentation here for a description of what this means.

Now that we have defined all the pieces necessary for the listRegistryKeysInGuest function, we can call it and iterate the results, which are an array of VcGuestRegKeyRecordSpecs:


            var vmList = VcPlugin.getAllVirtualMachines(null, "ws2019");

            var guestAuth = new VcNamePasswordAuthentication(false, "administrator", “P@ssw0rd!);
    
            var vm = vmList[0];
    
            var registryManager = vm.sdkConnection.guestOperationsManager.guestWindowsRegistryManager;
    
            var guestRegKeyNameSpec = new VcGuestRegKeyNameSpec("HKLM”, "WOWNative");
            var regKeyList = registryManager.listRegistryKeysInGuest(vm, guestAuth, guestRegKeyNameSpec);
            for each(regKey in regKeyList) {
                System.log("Key: " + regKey.key.keyName.registryPath);
            }
        

And the output:


            2022-07-03 19:28:13.823 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\BCD00000000
            2022-07-03 19:28:13.824 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\HARDWARE
            2022-07-03 19:28:13.825 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SAM
            2022-07-03 19:28:13.826 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SECURITY
            2022-07-03 19:28:13.827 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE
            2022-07-03 19:28:13.828 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SYSTEM

We have to go a few levels deep to get to the Key paths (regKey.key.keyName.registryPath) because the returned VcGuestRegKeyRecordSpec contains some sub-objects, more on this below.

Additionally, we can also provide a fourth, optional boolean parameter recursive to the listRegistryKeysInGuest function to step into each Subkey, and further Subkeys to return all Keys in the tree:


            registryManager.listRegistryKeysInGuest(vm, guestAuth, guestRegKeyNameSpec, true);
        

Output:


            2022-07-03 19:32:01.974 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\BCD00000000
            2022-07-03 19:32:01.975 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SECURITY
            2022-07-03 19:32:01.976 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE
            2022-07-03 19:32:01.977 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE\Microsoft\EAPSIMMethods\18\Identities
            2022-07-03 19:32:01.978 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE\Microsoft\EAPSIMMethods\23\Identities
            2022-07-03 19:32:01.979 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE\Microsoft\EAPSIMMethods\50\Identities
            2022-07-03 19:32:01.980 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModel\FileLaunchElevationBlockList
            (...etc...)
        

Note that if you list key recursively on a busy VM or via a busy vCenter, the listing can take longer than vRO's default timeout and fail.

Finally, you can filter the results with a final string parameter matchPattern:


            registryManager.listRegistryKeysInGuest(vm, guestAuth, guestRegKeyNameSpec, true, “EAPS”);
        

Output:


            2022-07-03 19:36:27.425 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE\Microsoft\EAPSIMMethods
            2022-07-03 19:36:27.426 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE\Microsoft\WindowsRuntime\ActivatableClassId\Windows.Networking.UX.EAPSimIdentityInput
            2022-07-03 19:36:27.427 +10:00info(com.mitnl.test/registryAccess) Key: HKLM\SOFTWARE\WOW6432Node\Microsoft\EAPSIMMethods
        

LISTING VALUES

Similar to listing Keys, we can list the Values in a key with the listRegistryValuesInGuest function. It accepts the same parameters as listRegistryKeysInGuest, including recursive and matchPattern, with the returned results being an array of VcGuestRegValueSpecs:


            var guestRegKeyNameSpec = new” VcGuestRegKeyNameSpec(“HKLM\\SOFTWARE\\DefaultUserEnvironment”, “WOWNative”);
            var regValueList = regMgr.listRegistryValuesInGuest(vm, guestAuth, guestRegKeyNameSpec);
            for each (regValue in regValueList) {
                System.log("Name: " + regValue.name.name + " Data: " + regValue.data.value);
            }
        

Output:


            2022-07-03 20:25:25.872 +10:00info(com.mitnl.test/registryAccess) Name: Path Data: %USERPROFILE%\AppData\Local\Microsoft\WindowsApps;
            2022-07-03 20:25:25.873 +10:00info(com.mitnl.test/registryAccess) Name: TEMP Data: %USERPROFILE%\AppData\Local\Temp
            2022-07-03 20:25:25.874 +10:00info(com.mitnl.test/registryAccess) Name: TMP Data: %USERPROFILE%\AppData\Local\Temp
        

CREATING A NEW KEY

In creating a new Key, we yet again use the same objects as previously, except the registryPath in our VcGuestRegKeyNameSpec will be the path to the new Key:


            var targetKey = new VcGuestRegKeyNameSpec("HKLM\\SOFTWARE\\newKey", "WOWNative");

            registryManager.createRegistryKeyInGuest(vm, guestAuth, targetKey, false);
        

The fourth boolean parameter, isVolatile, must be set to ‘false’ if you want the key to persist after a reboot.

DELETING A KEY

Deleting a key works as you might expect after making it this far. targetKey is a VcGuestRegKeyNameSpec:


            registryManager.deleteRegistryKeyInGuest(vm, guestAuth, targetKey);
        

CREATING A NEW VALUE

Creating a new value however is slightly more complex. The registry manager function is setRegistryValueInGuest which takes a VcGuestRegValueSpec. VcGuestRegValueSpec has a property name which is a VcGuestRegValueNameSpec. The VcGuestRegValueNameSpec has a property keyName, which is the key under which the new Value will be created, which is the familiar VcGuestRegKeyNameSpec. Finally the VcGuestRegValueNameSpec has a string property name, which is the name of the Value to be created.

Setting that chain up from scratch looks something like this:


            var newValue = new VcGuestRegValueSpec();
            newValue.name = new VcGuestRegValueNameSpec();
            newValue.name.keyName = new VcGuestRegKeyNameSpec("HKLM\\SOFTWARE\\newKey", "WOWNative");
            newValue.name.name = "NEWVALNAME";
        

The VcGuestRegValueSpec also has a data property. This property must be one of the classes which extend VcGuestRegValueDataSpec and determine the data type of the registry Value:


            newValue.data = new VcGuestRegValueStringSpec();
            newValue.data.value = "NEWVALDATA";
        

We can now use the newValue object:

registryManager.setRegistryValueInGuest(vm, guestAuth, newValue);

The VcGuestRegValueNameSpec’s name property can be an empty string. If this is the case, then the operation will occur on the Default value for the key specified.

You also use this function to update (overwrite) existing Values.

DELETING A VALUE

Finally, deleting a value uses the function deleteRegistryValueInGuest which takes a VcGuestRegValueNameSpec, which as seen above needs a VcGuestRegKeyNameSpec in addition to the Value name. Both can specified in the constructor:


            var targetKey = new VcGuestRegKeyNameSpec("HKLM\\SOFTWARE\\newKey", "WOWNative");
            var delValue = new VcGuestRegValueNameSpec(targetKey, “NEWVALNAME”);
    
            registryManager.setRegistryValueInGuest(vm, guestAuth, delValue);
        

OTHER NOTES

Using the vSphere API to access the guest uses VMware Tools, which is unreliable. You should wrap all of these commands in a try-catch structure and a loop if you want to retry a few times.

< Back