Refresh. What does that mean? To different people, it could mean different things. ‘Refresh’ and get a new page. Take a day off and ‘refresh’ your mind. Buy new hardware and replace the old. The list can go on. However, for me, ‘refresh’ takes me back to a job I had years ago.

Every Saturday, we would have to ‘refresh’ a few select servers. My team would be given a list of production servers that were required to be shutdown, cloned to a development site, reconfigured for the new site and everything brought back up. When done manually, this was a 24-36 hour ordeal. My job was to automate that process.

Back then, this was vSphere 3.5/4.0. Powershell/PowerCLI was a new thing. No one had ever heard about vCenter Orchestrator (now, known as vRealize Orchestrator). I had to automate this tedious process. I eventually wrote a 4000+ line Powershell program. I call it a program, because hell….. I had almost as many lines of code as Windows. Ok, that’s an exaggeration, but you see my point. It was huge.

It took me many months of trial and error to get the code to work the way I wanted. I would write and test code through the week in my homelab, then on Saturday – see if it actually would work. Eventually, I got it down to a science, and was able to curb the extended process to under 12 hours. Yes, it still took a full day — this was mainly due to the fact, that I had to move 100GB virtual machines across a 100Gb ethernet connection onto older non-efficient hardware. Why was the hardware never upgraded? I don’t know. My opinion on that matter was never heard. Hell, it was a NetApp Storage array that the company refused to turn on dedupe! How is that even possible?

Sidetracked!! Let me get us back on the rails.

So here I am ten years later, and guess what popped in my head this week. You guessed it. “Refresh”

Falcon Fury: Private WoW Server
Falcon Fury: Private WoW Server

Use Case:

I have a virtual machine that is a private game server that I run for my family and friends. The obstacle that I need to address is how to patch or modify the game server without experimenting on the same server we play on. I want to ‘refresh’ this machine. I want to clone and reconfigure the virtual machine’s IP and hostname. This will allow me to have both the “production” game server and the “development” game server running simultaneously.

How to do this?

While there are many ways to achieve the goal of my use case, I wanted to do this in vRealize Orchestrator as a workflow. I knew that vRO may have existing built-in workflows that I could re-use without having to reinvent too much of the wheel. I also wanted to promote the workflow to be a Catalog Item.

The work begins

This article assumes that you already have a working vSphere and vRealize Automation environment. It also assumes that you have a working understanding of how to use vRealize Orchestrator and vRealize Automation.

My environment consists of the following:

  • vSphere 6.7 U3
  • vRealize Automation 8.1 HF2

Known Static Variables:

  • Virtual Machine Name: WoW
  • New Virtual Machine Name: wow-clone
  • IP address: <new static IP address>

Going into building the workflow, I knew the existing virtual machine name to clone, the new virtual machine’s name, and the new IP address I wanted.

Workflow Creation

Rough Draft Workflow
Rough Draft Workflow

TIP: When you are working on creating new workflows, use a whiteboard to draw out what you want to accomplish. You may not know the exact details for each step, but this will help you visualize where to start.

The whiteboard drawing is actually of version 0.2.x of the workflow draft. At first, I had started with the clone workflow. During my testing, I realized that in reality, I may already have an existing copy of the VM already in place — as I had experienced during the testing. So I had to add a few elements to power down the existing VM and remove it before attempting the clone.

I was also discovering that I got tired of re-inputting all of the variables to make the workflow run. Knowing that for my end-state, I wanted to automate this, and that the variables were pretty static, I decided to convert all of the inputs into variables.

Problem #1

Doing this introduced a problem. There were some times where the development VM: “wow-clone” may not exist. Because of this, I could not set the variable: fetchvm to a VC:VirtualMachine object. If this variable wasn’t set, the workflow would error – every time. Setting it to a string type variable failed as well – as it wasn’t a VirtualMachine object that the Power Down workflow could manipulate.

The workflow starts with a scriptable task called Welcome. Here, is where I had been identifying some of my variables. I needed to add some code to convert the string variable: vmname to the VC:VirtualMachine object variable: fetchvm. fetchvm would be the VirtualMachine object that will get powered down, removed, and created.

Added Code:

The following code was put into the Welcome scriptable task. While it may look a tad odd or that of a newbie, I like to create as clean of code as possible with plenty of comments and log entries. This makes for easier debugging. Additionally, if you get into this practice, it makes for easier understanding for someone to come behind you to work or troubleshoot potential code that you may leave behind.

///Identify clone name and start logs cleanly
var vmname = "wow-clone";
System.log("....................Starting the Cloning operation..........:  ");
System.log("....................Check to see if VM exists...............:  ");
System.log("....................Variables...............................:  ");
System.log(".........................Search Name........................:  " +vmname);

///Convert string into vm object
query = "xpath:name='"+vmname+"'";
vmnames = VcPlugin.getAllVirtualMachines(null,query)[0];
var fetchvm = vmnames;

///Validate the variable
if (fetchvm == null){
    System.log(".........................Seaching Name......................:  MISSING");
else {
    System.log(".........................Virtual Machine Name..........FOUND:  ";
Problem #2:

Great. Now that the code is here, when the virtual machine “wow-clone” didn’t exist, the script would fail to run. I needed to add a way to check to see if the VM existed.

Thankfully, vRO has an element built-in that allows for just such a task. It’s the Decision element. I drug this onto the workflow canvas between my Welcome scriptable task and the Power Down workflow. I then created additional scriptable tasks to indicate where the VM was there or not.

Is the VM here?
Is the VM here?

It took me a few attempts at making this thing work reliably. I could not just set it to “simple” mode and be done with it. I wound up having to insert some javascript into it. This bit of code made it reliable.

if (fetchvm == null)return false;

This addition to the workflow got it to work reliably. Now…. Onto the next hurdle.

Problem #3

To clone the VM, I found there was an existing workflow called Clone thin provisioned, Windows with single NIC and credential. I added this workflow element onto the canvas and renamed it Cloning Workflow.

So how is this a problem, you ask?

Well. This particular workflow has quite the number of variables in it. However, it does exactly what I wanted. It clones a virtual machine, renames it, and assigns a new IP. Awesome! Exactly what I wanted. The problem was I would go to run my workflow, and discover that there were several variables that are not identified as required, that were indeed required.

To save you the hassle, here are a few of the problematic variables that I had to hardcode. Most of the variables are self-explanatory, but like I said, some of them you didn’t know you needed, until you ran the workflow.

  • newAdminPassword – This is a plain text string. (Don’t ask, I agree with you.)
  • licenseMode – either perSeat or perServer
  • licenseUsers – If you set the above to perServer, you must enter the number of licensed Users.
  • inTimezone – Set to your local timezone
  • doSysprep – true or false. if you are not converting this into a template, you must set it to true.
  • fullName – any name of user
  • orgName – company or organization name that purchased the Windows license
  • clientName – set this to the name variable.

This took me 39 attempts to get it correct each of the variables.

Final Workflow

What does the finished product look like?

Workflow Final Draft
Workflow Final Draft

As you can see, it’s fairly straight forward and not too far off from my whiteboard concept.

What is custom, and what is out of the box? Here’s the breakdown:

  • Welcome – Scriptable task. Described above with that exact code block.
  • Decision – OOTB element, but customized decision with the previously mentioned javascript.
  • Power Down – OOTB Workflow element: “Power off virtual machine and wait”
  • Remove VM – OOTB workflow element: “Delete virtual machine”
  • Cloning VM – OOTB workflow element: “Clone thin provisioned, Windows with single NIC and credential”
Workflow Logs
Workflow Logs

The scriptable tasks that are there are used to confirm progression points within the workflow. They could be completely optional, but they make for really great log entries.

You may be asking why I wanted to separate the Power Down and Remove VM workflows. The answer is basically, I wasn’t sure if I wanted to delete the VM until later. With the two separate workflows, I can remove the “Remove VM” workflow if I ever change my mind.

vRealize Automation

Once the workflow was created, I wanted to add it to the Catalog within vRealize Automation. This wasn’t hard to do. TIP: Just make sure that the data collection for vRO has run. Otherwise, you may need to wait up to ten minutes.

Quick and Dirty Steps: (Maybe I’ll detail this in the future with pics)

  • Open up the Service Broker, navigate into Content & Policies and add a vRO Services Content Source with the vRO Workflow: WoW Refresh item.
  • I then shared the Content Source with my Project: Research.
  • (Optional) You can edit the Workflow Content and add an icon and custom form.
vRA Catalog Item: WoW Refresh
vRA Catalog Item: WoW Refresh


After working through the hurdles, the workflow was reliable. I was able to run it from vRA. It would check to see if a previous clone existed, if one did, it would power it down, and remove it. Otherwise, it would start cloning my “production” WoW Server and reconfigure the clone to not conflict with the original on the network.

While this may seem to be easy to some, I document my efforts here because it may inspire some people to create their own similar automation. I needed to do this myself, and I was inspired by my own previous work using PowerCLI. Back then, I googled a lot and struggled to find someone doing the same thing I was trying to do.

As always: DISCLAIMER: Use at your own risk. Do not use this code within your production environment.

Print Friendly, PDF & Email