PowerCLI Report – Review SRM Source & Destination Network Settings


Was asked to review SRM Recovery Plans especially on source and destination network settings that gets customised during failover. Due to large number of virtual machines to review, it was not ideal to go through recovery plans one by one. Thus, came up with a script to generate an output for review.


  • vCenter Server 5.0 U2
  • SRM 5.0 U2
  • PowerCLI 6.0 Release 1


First of all, I tried SRM API through PowerCLI, however the SRM API version was not at 2.0 so that I did not have access to all APIs. Hence, I had to find an alternative. Doing some research, found an executable called dr-ip-reporter.exe which allowed me to generate an XML file with all information that I needed. One thing popped up in my mind was to convert XML file into CSV. 

Running the executable to get XML output, copy it to where PowerCLI is installed was a little bit troublesome. Hence, came up with a plan to use psexec.exe to run the dr-ip-reporter.exe remotely and save the output as a variable. However, the executable did not have arguments for username and password. Therefore, this had to be ran manually.

Steps below:

  1. Login to Windows server where SRM server is installed.
  2. Open up a command prompt and run dr-ip-reporter.exe. Run the following command:
    • C:\Program Files\VMware\VMware vCenter Site Recovery Manager\bin\​dr-ip-reporter.exe –cfg C:\Program Files\VMware\VMware vCenter Site Recovery Manager\config\vmware-dr.xml –out C:\SRM\IP.xml –vc “vCenter IP or hostname” -i
    • 1
  3. Modify IP.xml file, the very top line “<?xml version=”2.0″ encoding=”UTF-8″?>” to “<?xml version=”1.0″ encoding=”UTF-8″?>” as per the following screenshot below:
    • Before
      • 2
    • After
      • 3

Once the pre-requisite is done:

  1. Copy the IP.xml and paste it to where  SRM-XML-Convert.ps1 script. 
  2. Run the SRM-XML-Convert.ps1
  3. Check the output, srm_final_output.csv

Sample Output

Looking at output below, you would be easily able to identify that:

  1. For TEST1 VM, recovery site DNS servers are missing
  2. For TEST2 VM, both protection and recovery site network setting is missing
  3. For TEST3 VM,  recovery site network setting is missing
"Protection Group","VM","Site","IP Address","SubnetMask","Gateway","DNS Servers" 


Import IP.xml generated from DR IP Reporter 
Foreach line of IP.xml file, select components needed. 
In this case: 
    Protection Group 
    Name of the VM 
    IP Address 
    Subnet Mask 
    DNS Servers 

[xml]$input_file = Get-Content IP.xml​
$output = $input_file.DrMappings.ProtectionGroups.ProtectionGroup | Sort Name | ForEach-Object {
    $protection_group = $_.Name
    $_.ProtectedVm | Sort Name | ForEach-Object {
        $vm = $_.Name
        $_.CustomizationSpec | Sort Site | ForEach-Object {
            $site = $_.Site
            $ip_settings = $_.ConfigRoot.e.ipSettings
            if ($ip_settings) {
                $ip_address = $ip_settings.ip.ipAddress
                $subnetmask = $ip_settings.subnetMask
                $gateway = $ip_settings.gateway.e."#text"
                if ($ip_settings.dnsServerList.e) {
                    $dns_server = [string]::Join(",", ($ip_settings.dnsServerList.e."#text"))

            "" | Select @{N="Protection Group";E={$protection_group}},
                        @{N="IP Address";E={$ip_address}},
                        @{N="DNS Servers";E={$dns_server}}
            $ip_address = "";
            $subnetmask = "";
            $gateway = "";
            $dns_server = "";

$output | Export-Csv -UseCulture -NoTypeInformation srm_final_output.csv​
Disconnect-VIServer * -Confirm:$false​

Hope this and feel free to contact me for any clarifications 😀

vCenter Server 6.0 – Licensable Entity Does Not Exist


Recently, I worked on an issue where vCenter Server Appliance 6.0 U1 was rebuilt and was not able to assign vCenter Server license key with the following error message:


After a review, it was found out that the license key was not removed before decommissioning the old VC. As a result, old VC asset was registered with the license key and removing the asset thrown up an error:

License entity does not exist


The vSphere environment was set as the following:

  1. 1 x vCenter Server Appliance 6.0 U1
  2. 1 x Windows vCenter Server 6.0 U1
  3. 1 x Appliance External PSC 6.0 U1
  4. 1 x Windows External PSC 6.0 U1
    • 1 x SSO domain
    • 1 x SSO site

What Happened?

  1. Decommissioned VCSA 6.0 U1 without removing VC license key from the license page
  2. Rebuilt VCSA 6.0 U1 with external PSC with the same configuration as before
  3. Existing PSC thinks that the old asset still exists


Worked with VMware Support and they advised that the issue is due to the old entity still reamining in the VMware Directory Service database whereas the old asset was removed. The solution was simple enough, remove the old entity.

To do the work, JXplorer was required. Download it here.

  1. Install JXplorer and run it. On the left top corner, click Connect to a DSA
    • 2
  2. Use the following to connect to VMware Directory Service database:
    • Host: FQDN of the Host
    • Protocol: LDAP v3
    • Base DN: dc=vsphere,dc=local
      • This is the default SSO domain, vSphere.local
      • If it’s not default, change it accordingly
    • Level: User + Password
    • User DN: cn=administrator,cn=users,dc=vsphere,dc=local
      • Again, this is the default SSO domain. If it’s not default, change it accordingly
    • Password: password for administrator@vsphere.local
    • 3
  3.  Once connected, expand out like the following:
    • 4
  4. Search for the LicenseEntity where:
    • vmwLicSvcLicenseName: vCenter Server 6 – vCenter Server Name
    • vmwLicSvcLicenseSerialKeys: Equal to the license key that you cannot remove
    • 5
  5. Before deleting the problematic LicenseEntity,  take snapshot on:
    • 2 x vCenter Servers
    • 2 x external PSCs
  6. Delete the LicenseEntity
  7. Once deleted, SSH to PSC and restart the following services in order:
    1. VMware Security Token Service
    2. vmware-stsd
    3. VMware Identity Management Service
    4. vmware-sts-idmd
    5. VMware License Service
    6. vmware-cis-license
  8. The actual commands below:
    1. service-control –stop vmware-stsd
    2. service-control –start vmware-stsd
    3. service-control –stop vmware-sts-idmd
    4. service-control –start vmware-sts-idmd
    5. service-control –start vmware-cis-license
    6. service-control –start vmware-cis-license
    7. 6
  9. When services are restarted, ensure the Asset is gone from the licensing page
  10. Now, you will be able to remove the license key
  11. Then, add the license key back asssigning it to the new VC
  12. Delete the snapshots

Hope this was helpful and feel free to leave a comment for any clarifiations 😀

vRO Deepdive Series Part 4 – Log Handling, Exception Handling and Failing Back


Continuing the vRO deep dive series and this is the 4th part. This will be discussing log handling, exception handling and failing back.

Feel free to revisit the previous deep dive series:

Log Handling

vRO provides 3 types of log handling:

  • Log
  • Warning
  • Error

Let’s do some exercise and see the difference between them.

First of all, create a workflow calling it what you would like to (I called it “hi”) and navigate to the Log tab under Schema. You will find 7 default loggings:

Screenshot 2015-06-16 09.44.53

For the starters, let’s try System log out. Drag and drop the element in like the following:

Screenshot 2015-06-16 09.45.39

Edit the System log and navigate to Scripting. You will find an auto-generated script “System.log(text);”.

Screenshot 2015-06-16 09.45.53

Let’s take a look at System warning and error as well, drag and drop others like the following screenshot:

Screenshot 2015-06-16 09.48.46

Edit the System warning and it will show you a similar script as System log, “System.warn(text);”

Screenshot 2015-06-16 09.46.43

Pretty much identical for System error, “System.error(text);”

Screenshot 2015-06-16 09.46.56

Let’s run the workflow and see how they look differ on the vRO logging tab. Create an attribute called attrText and the value to be “Different types of logging”.

Screenshot 2015-06-16 09.47.31

For each element, finish up the visual binding like the following:

Screenshot 2015-06-16 09.47.54

Time to run the workflow. Execute and it will present 3 different types of logging:

  • Log in a normal font
  • Warning in bold
  • Error in red and bold

Screenshot 2015-06-16 09.49.09

One thing I would like to highlight before moving on is that you do not need to use the above element in order to do logging. Within a scriptable task, you could always use System.log(text), System.warn(text) or System.error(text). Will go a bit deeper into this shortly.

Time for a proper exercise! For the next, I will be going through creating a network adapter on a virtual machine with different types of network adapters.

First of all, remove all 3 logging elements made previously and drag and drop a scriptable task. Navigate to the Scripting tab and paste the following script in:

System.log("Adding a virtual NIC to this VM with portgroup: " + Portgroup.name);
// Create connectable info for network
var connectInfo = new VcVirtualDeviceConnectInfo();
connectInfo.connected = true;
connectInfo.startConnected = true;
connectInfo.allowGuestControl = false;
// Create Network BackingInfo
var netBackingInfo = new VcVirtualEthernetCardDistributedVirtualPortBackingInfo();
netBackingInfo.port = new VcDistributedVirtualSwitchPortConnection();
netBackingInfo.port.switchUuid = Portgroup.config.distributedVirtualSwitch.uuid;
netBackingInfo.port.portgroupKey = Portgroup.key;
// Create VirtualNetwork
if (Type.toUpperCase() === "VMXNET3") {
vNetwork = new VcVirtualVmxnet3();
} else if(Type.toUpperCase() === "E1000E") {
vNetwork = new VcVirtualE1000e();
vNetwork.backing = netBackingInfo;
vNetwork.addressType = "Generated";
vNetwork.connectable = connectInfo;
// Create Network ConfigSpec
var deviceConfigSpec = new VcVirtualDeviceConfigSpec();
deviceConfigSpec.device = vNetwork;
deviceConfigSpec.operation = VcVirtualDeviceConfigSpecOperation.add;
var configSpec = new VcVirtualMachineConfigSpec();
var configSpecArray = new Array(); 
configSpec.deviceChange = configSpecArray;
// Run the task
Task = VM.reconfigVM_Task(configSpec);

Once the script is in place, create three inputs as per the following screenshot:

Screenshot 2015-06-16 11.04.08

As depicted above, the workflow will require 3 inputs from the end users; virtual machine, portgroup and type. For the type, instead of asking the end user to manually type the input in, it would be better to pre-define a list and let them select one. This would make it easier for both workflow developers and users.

Go back to the General tab, change the type of the attribute attrTypeList to Array of string and add VMXNET3 and E1000E:

Screenshot 2015-06-16 11.04.31

Screenshot 2015-06-16 11.04.26

Once done, go to Presentation tab, select Type, choose “Predefined list of elements” and link it to pre created attribute attrTypeList.

Screenshot 2015-06-16 11.05.04

Screenshot 2015-06-16 11.05.14


Lastly, finish off the Visual Binding:

Screenshot 2015-06-16 11.05.47

All done! Let’s run the workflow to ensure it does the job. For the next example, I will be choosing a portgroup with VLAN1153 and VMXNET3 network adapter.

Screenshot 2015-06-16 11.18.10

Submit the request. Once the workflow completes, see if VMXNET 3 network adapter with portgroup VLAN1153 has added:

Screenshot 2015-06-16 11.19.01

Let’s create another one with VLAN1153 in E1000E type. Submit another request:

Screenshot 2015-06-16 11.19.50

Now we are confident that the workflow creates a portgroup as intended, it’s time to go through the logging. What I will be showing shortly is:

  • Selecting VMXNET3 = informational message will be logged
  • Selecting E1000E = warning message will be logged

Go back to the scriptable task and modify like the following:


// Create VirtualNetwork
    if (Type.toUpperCase() === "VMXNET3") {
    vNetwork = new VcVirtualVmxnet3();
} else if(Type.toUpperCase() === "E1000E") {
    vNetwork = new VcVirtualE1000e();


// Create VirtualNetwork
if (Type.toUpperCase() === "VMXNET3") {
    vNetwork = new VcVirtualVmxnet3();
    System.log("VMXNET3 Virtual Adapter will be created");
} else if(Type.toUpperCase() === "E1000E") {
    vNetwork = new VcVirtualE1000e();
    System.warn("VMXNET3 is recommended, but E1000E will be created");

Have a look at the example runs below:

  • 1 x VLAN997 VMXNET3 portgroup

Screenshot 2015-06-16 11.26.38

  • 1 x VLAN997 E100E portgroup

Screenshot 2015-06-16 11.28.08

This is how informational or warning message could be used. For the error message, it will be discussed in the next topic “Exception Handling”.

Exception Handling

An exception handling in the programming world is defined as

Exception handling is the process of responding to the occurrence, during computation, of exceptions – anomalous or exceptional conditions requiring special processing – often changing the normal flow of program execution

Why would you need to do exception handling? The reason is simple, when something never expected happens, information of the exception has to be handled, e.g. error message logged, locate where it happened…etc, which will allow easier troubleshooting for the developers.

The best way to catch an exception is to use try & catch:

try {
    ...... script
} catch (e) {

Whatever fails in try statement, the error message will be saved to the variable e and then logged as an error message.

Will be continuing with the example used in the previous section. Edit the scriptable task and replace the whole lines with the following script:


try {
    System.log("Adding a virtual NIC to this VM with portgroup: " + Portgroup.name);
    // Create connectable info for network
    var connectInfo = new VcVirtualDeviceConnectInfo();
    connectInfo.connected = true;
    connectInfo.startConnected = true;
    connectInfo.allowGuestControl = false;

    // Create Network BackingInfo
    var netBackingInfo = new VcVirtualEthernetCardDistributedVirtualPortBackingInfo();
    netBackingInfo.port = new VcDistributedVirtualSwitchPortConnection();
    netBackingInfo.port.switchUuid = Portgroup.config.distributedVirtualSwitch.uuid;
    netBackingInfo.port.portgroupKey = Portgroup.key;

    // Create VirtualNetwork
    if (Type.toUpperCase() === "VMXNET3") {
        vNetwork = new VcVirtualVmxnet3();
        System.log("VMXNET3 Virtual Adapter will be created");
    } else if(Type.toUpperCase() === "E1000E") {
        vNetwork = new VcVirtualE1000e();
        System.warn("VMXNET3 is recommended, but E1000E will be created");

    vNetwork.backing = netBackingInfo;
    vNetwork.addressType = "Generated";
    vNetwork.connectable = connectInfo;
    // Create Network ConfigSpec
    var deviceConfigSpec = new VcVirtualDeviceConfigSpec();
    deviceConfigSpec.device = vNetwork;
    deviceConfigSpec.operation = VcVirtualDeviceConfigSpecOperation.add;
    var configSpec = new VcVirtualMachineConfigSpec();
    var configSpecArray = new Array();
    configSpec.deviceChange = configSpecArray;
    // Run the task
    Task = VM.reconfigVM_Task(configSpec);
} catch (e) {

Causing an exception with this workflow is quite simple, just pick a portgroup that the virtual machine doesn’t have access to. In this example, VLAN23 was chosen:

Screenshot 2015-06-16 11.50.40

Since VLAN23 portgroup doesn’t exist, it now presents an error message saying “vNetwork is not defined”. One odd thing here is that looking at history of the workflow, it says the workflow was successful. Why is this? It’s because the exception was caught but wasn’t thrown properly, i.e. the workflow was not terminated. The way of throwing an exception is using “throw” statement. Add the throw statement like the following:


} catch (e) {
} catch (errorCode) {
    throw errorCode;

Once the change is made, the error will be thrown when an exception happens. One thing to consider is, where will it be thrown to? The exception must be handled once it is thrown.

Go back to the Schema and under the Generic tab, you will be able to find “Throw Exception” element.

Screenshot 2015-06-16 11.51.06

Throw exception element could be treated as End workflow but the difference is, the workflow was successful or failed.

Drag and drop the Throw exception element on the Scriptable task and a dotted red arrow will be created.

Screenshot 2015-06-16 11.51.21

Doing this will automatically create an attribute called errorCode. The purpose of this attribute is to catch any exception was thrown and forward it to the Throw exception element. This is why the variable e has been modified to errorCode earlier.

Saving the workflow will cause an error saying “Exception binding was not set”. This is because the workflow expects the scriptable task to bind the error message as an attribute. Edit the scriptable task, navigate to Exception and bind it to errorCode:

Screenshot 2015-06-16 11.51.30

Also, do the visual binding like below:

Screenshot 2015-06-16 11.52.05

Let’s run the workflow again choosing VLAN23. Unlike the previous example, now it will end in the throw exception state (the Throw exception element is highlighted).

Screenshot 2015-06-16 11.53.30

This is how you handle exceptions and will be moving onto fail-back process.


In my opinion, fail-back is one of the important aspects when developing a workflow. Continuing with the example above, let’s say there are 3 more tasks after creating a network adapter which I will be calling X, Y and Z and if task Y fails, what would you do to the network adapter created in the previous stage? The answer is obvious, it has to be removed, you don’t want the users to run the workflow multiple times ending up with 10 identical network adapters on a single virtual machine.

Let’s implement a simple fail-back process in this workflow. First of all, create an attribute called attrDevice with type to be Any (well there is no type with VC:VirtualDevice). This will be used to keep the device information.

Screenshot 2015-06-16 13.39.04

Once done, drag and drop 3 scriptable tasks between Create Network Adapter scriptable task and End element and call them Task X, Task Y and Task Z accordingly. Make sure you bind errorCode as the exception variable across 3 scriptable tasks and also, hover over and drag red arrow to Throw element.

Screenshot 2015-06-16 13.42.03


Screenshot 2015-06-16 13.42.11

Screenshot 2015-06-16 13.41.20

When task X,Y or Z fails, we want to delete the network adapter created. To do this, simply drag and drop a scriptable task between Task X and the Throw element and call it Remove Network Adapter:

Screenshot 2015-06-16 13.43.54

The problem in the above screenshot is that when the Task Y fails, it will just throw an exception without failing back. It will go directly to the Throw exception element. To correct it, click on the red line between the task Y and the Throw exception element, press delete and re-join it to Remove Network Adapter task. Repeat it to Task Z and the final state will look like the following:

Screenshot 2015-06-16 13.45.08

Paste the following script into Remove Network Adapter scriptable task:

try {
    System.error("An error has occurred, removing the created network adapter: " + attrDevice);

    var deviceConfigSpec = new VcVirtualDeviceConfigSpec();
    deviceConfigSpec.device = attrDevice;
    deviceConfigSpec.operation = VcVirtualDeviceConfigSpecOperation.remove;

    var configSpec = new VcVirtualMachineConfigSpec();

    var configSpecArray = new Array();

    configSpec.deviceChange = configSpecArray;

    Task = VM.reconfigVM_Task(configSpec);
} catch (e) {
    errorCode = e;
    throw errorCode;

And also, finish off the Visual Binding:


Screenshot 2015-06-16 13.46.54


Screenshot 2015-06-16 13.47.34

All done, let’s run and see the fail-back works. The following depicts the virtual machine has two network adapters, VLAN444 and VLAN1153:

Screenshot 2015-06-16 15.17.26

Let’s intentionally throw an exception in Task Y. Do the Visual Binding for errorCode and type the following in the scripting field:

errorCode = "This is intentional";
throw errorCode;

Let’s run it!

Screenshot 2015-06-16 15.20.41

It has thrown an exception at the Task Y and looking at how many network adapters the virtual machine has, you will see that the network adapter wasn’t created. Fail-back was successful!

Screenshot 2015-06-16 15.21.50


Hope this blog post was helpful and as always, feel free to contact me for any clarifications or help.

The next series will cover “Introduction to Relationship Between vRO & vRA” which is a big topic, stay tuned! 😀