Disclaimer: I do not guarantee accuracy of the numbers presented. These numbers were collected from public available data. The data was collected on February 6. 2021.
There are four VCDX certification paths
Data Center Virtualization (VCDX-DCV)
Cloud Management & Automation (VCDX-CMA)
Desktop and Mobility (VCDX-DTM)
Network Virtualization (VCDX-NV)
There are 42 VCDX that hold two VCDX certifications.
There are 6 VCDX that hold three VCDX certifications.
There is only 1 VCDX that holds all four VCDX certification.
If you would like to know more about each VCDX, the effort it takes to become a VCDX or more information about VCDX in general, go to https://vcdx.vmware.com
VCDX around the globe
VCDX distribution globally
Other are all countries together that have less than 5 VCDX.
VCDX in each country
VCDX in the United States
VCDX distribution in the United States
Other are all states combined that have less than five VCDX.
VCDX in each state of the United State of America
VCDX by company
VCDX distribution by company
Companies that have less than three VCDX were combined.
If you have successfully registered your vRealize Orchestrator (vRO) in the vCenter Web Client you can add your workflows as a context action. Follow Add vRO 8.x extension to vCenter Web Client for details on how to register the vRO in vCenter. What does context action mean. Well it means that your workflow becomes selectable from the vRO menu item in the vCenter Inventory. For example you add your workflow to a context action of a virtual machine. If you then right click on any virtual machine and then select vRealize Orchestrator -> Run Workflow… you can then select your workflow. In order for this to work you must define what inventory object should be linked with what workflow. If an input parameter of your vRO workflow is of type Virtual Machine you would want this to link to Virtual Machine objects in the web client. That way your workflow will get pre-filled with Virtual Machine from which you started the workflow from. Here are the steps for adding the context action.
If the integration of vRO as extension was successful you should see a new menu item on the home screen. Click on the vRealize Orchestrator menu item.
Home Menu
If you successfully connected your vRO server to the vCenter Server. you should see your vCenter Server on the home screen of the vRO menu.
Summary
Click on Context Actions and then on Add to start adding your workflow.
Context Actions
Now enter the name of your workflow in the search field and hit enter. The workflow should now show in the list below. Check the checkbox next to your workflow. Select the type of object you want to associate your workflow with. Meaning which vCenter inventory object should show your workflow. If you only have one vCenter inventory object, this field will be pre-filled. Click ASSIGN and you are done.
In previous versions of vRealize Orchestrator and with the vCenter Flash Web Client, it was very straight forward to add the extension to the vCenter Flash Web Client. You simply ran the vRO workflow “Register vCenter Orchestrator as a vCenter Server extension” and that was it. If you do that with vRO 8.x you will see an error in vCenter that it could not download the plugin. The reason is that the plugin is missing on the vRO server and therefore vCenter cannot download it. So what we need to do is to download the plugin manually and copy to the vRO Server and then run the workflow to register. The detailed steps are described here: Configure vRealize Orchestrator Plugin for vSphere Web Client. Essentially you have to download the plugin from here Technical Preview of Orchestrator plug-in for vSphere Web Client and then copy the plugin with scp to /data/vco/usr/lib/vco/downloads/vco-plugin.zip on the vRO server and then run the workflow mentioned above. This however does not integrate into the HTML5 client, only in the flash client. Now you say that vSphere 7 doesn’t have a flash client. Yes, you are right, however you still have to do this step. For the HTML5 client we need an additional step. We need to download another plugin and copy it to the vCenter Server. The detailed steps are described here: Install vRealize Orchestrator Plug-in for vSphere Client.
Change default shell to bash so that you can copy with scp. There might be other methods to accomplish this but changing default shell is one way. Connect with SSH to VCSA
This is all Beta and no official support for vSphere 7. I however followed these steps in my home lab and the plugin worked flawlessly, even with vSphere 7. For a production environment you want to wait till this is all supported. The following was mentioned as a response to the question when this will be ready for production. “We are considering to release it with vRO 8.3 if there are no change in plans.” We are now at vRO 8.1.
I recently posted a post with a workflow that updates the vCenter Server Appliance. For this to work we have to add the vAPI endpoint first. The endpoint name must be the VCSA hostname. The workflow uses the vCenters guest full qualified hostname to connect with the vAPI endpoint. I quickly explain how to add the vAPI endpoint. It is actually pretty straight forward. You need to start the workflow “Import vAPI metamodel”. You would think “Add vAPI endpoint”, but no, import comes first.
Import vAPI metamodel
Provide the required information. The vAPI endpoint URL is simply the full qualified domain name https:// url followed by /api. For the user name the user administrator@vsphere.local will work fine. “Do you want to add vAPI endpoint using the same settings?” this will then add the vAPI endpoint. That is it. If the workflow completes successful you can then use the vAPI endpoint to use the vCenter REST API. This is a prerequisite step for running my “Update VCSA” workflow.
I have created a vRealize Orchestrator (vRO) workflow that updates VCSA. If integrated into the vSphere Web Client it is just one click from the workflow to start an update of the vCenter – VCSA. There are a couple of options that you can change. Of course then it is more than one click. Download at the very end.
The workflow performs a couple of operations, not just the update itself. The idea is that you could schedule the update during times you are not in the office and perform other necessary operations like snapshot and backup and health check.
Flow
If vRealize Orchestrator (vRO) is integrated with the vSphere Web Client in order to start the workflow, you need to right click on the vCenter (VCSA) VM and then navigate to the bottom of the menu to vRealize Orchestrator -> Run Workflow…
Start a workflow from the vSphere Web Client
Then you need to select the workflow to run. In our case Update VCSA. In order for this workflow to show here, it must have been configured as a context action. I will explain this in a future blog post.
Select Update VCSA workflow.
The workflow will connect to the VCSA through the vAPI endpoint and collect available patches. If it found multiple patches you will have to select the one you would like to install. If there is only one patch, maybe because you are using a local https repository, you can click run. That would be your one click update.
General tab
The Options menu appears once patches were found. Select the Options tab to see more options. By default the workflow takes a VM Snapshot. The variable reqFreeSpaceinDS is set to 200. This means that at least 200GB (plus VM memory) must be available as free space in the vCenter VMs datastore in order for the workflow the create a snapshot. By default the workflow also takes a backup. It picks this information from the VCSA backup schedule. If there is no schedule set, you need to provide the Backup Location and Backup User parameter manually. The variable backupUserDefaultPasswd can be set to the password for the backup location. If none is set, you need to specify the password here. Email address is optional. If you specify an email the result of the backup will be send to that email address.
Options
In the Error Handling tab is the option to Ignore Health or Services. What that means is that the workflow checks for the VCSA health and if all services that are set to start automatically are start and healthy. By default the workflow will not continue to proceed with the update (including taking snapshot and backup) if this check fails. If you want to continue the update despite these checks failed you can select that option here.
Error Handling
Clicking Run in the lower right starts the update. If “Stay on current screen” is left unselect, you are automatically taken to the Workflow Run screen.
Start workflow
In the Workflow Run screen, you can monitor the state of the workflow and observe the event log of the workflow. It will display events happening during update. If you are updating from a local https repository it should take 35 minutes for a tiny VCSA. If you are updating from the internet it can take significantly longer. Also if you have a big VCSA VM the backup can take longer.
Workflow Run
You can also observe the backup state in the The vCenter Server Appliance Management Interface (VAMI).
Backup Job.
The workflow also posts events in the VMs event log.
VM Event log
If you have specified an email address it will send an email to that address with the final result of the update.
Email example
Below is a short demo of the workflow.
Demo of workflow
DISCLAIMER: Use at you own risk. I am not liable for any damage caused by this workflow package, workflow, file or code.
The worflow is free to use. Give credit where credit is due. Do not claim this work as your own.
The general purpose of my posts is more to show you how to do it and not to do the work for you. In the spirit of: “If I teach you how to fish you have fish for the rest of your life instead of me giving you a fish and you only have a fish for a day.” Therefore I will not go through all possible operations but I think it will be straight forward to apply the principle of the operations I will highlight. So let’s get to work. The list operation is the one that will check for the new updates, this is the one that we start with.
So we see here there are two parameters the query takes, source_type and url. Both of type string. url being optional, source_type mandatory. Source_type can be “LAST_CHECK”, LOCAL or LOCAL_AND_ONLINE. Before we can run anything we need to connect first. If you have read my previous post on the rest API you already know what to do.
#Connect to our VCSA first.
$cisConnection = Connect-CisServer -server vcenter.txusa.cloud
## Get the object. This is pretty much always the same we, translate the name from the API.
$getService = Get-CisService -Name "com.vmware.appliance.update.pending"
## Ignoring the optional parameter URL and only providing parameter to check CD and online.
$getService.list("LOCAL_AND_ONLINE")
Now here is the thing. The request can potentially fail. I see it fail when there simply was no new update with following error.
A server error occurred: ‘com.vmware.vapi.std.errors.internal_server_error’: Error in method invocation [Errno 2] No such file or directory:
‘/storage/core/software-update/updates’ (Server error id: ‘vapi.method.invoke.exception’). Check $Error[0].Exception.ServerError for more details.
So we must use a try and catch. This means we try to run the operation and if it fails we will catch the error or do what ever when it fails.
$getService = Get-CisService -Name "com.vmware.appliance.update.pending"
try
{
$checkResult = $getService.list("LOCAL_AND_ONLINE");
}
catch
{
#We catch the error and search for the known error
if(Error[0].Exception -like "*com.vmware.vapi.std.errors.internal_server_error*")
{
write-host "No such file or directory"
}
else
{
#An unknown error message
write-host "Something went wrong."
}
}
#If up to date and there is no error $checkResult will be empty.
if($checkResult)
{
#For this example we are only interested in the version
$patchVersion = $checkResult.version
}
The entire $checkResult would look like this but we are only interested in the version because we need it later.
Help : @{Documentation=The {@name Summary} {@term structure} contains the essential information about the update; version=; description=; priority=; severity=;
update_type=; release_date=; reboot_required=; size=}
severity : CRITICAL
update_type : FIX
size : 1833
reboot_required : True
release_date : 1/17/2019 12:00:00 AM
description : @{Help=; args=System.Collections.Generic.List`1[System.String]; default_message=Patch for vCenter Server Appliance 6.7.0; id=com.applmgmt.plain_message}
priority : LOW
version : 6.7.0.21000
Next is stage_and_install. This one is a little but more complicated. Parameter is version and a user_data object. We got the version from the previous call but now we also need to create the user_data object. This gave me a lot of headache, lots of try and error. We assume we are already connected.
#We know this part
$getService = Get-CisService -Name "com.vmware.appliance.update.pending"
#This is how you create a user_data object
$user_data = $getService.help.stage_and_install.user_data.Create()
#Then you need to add the user. I was not sure what to put here but I found out
#that it did not matter at all as long as the structure is right.
#Add two elements to the array.
$user_data.add("whatever","whatever")
#Now do the stage and install. Provide the version that we got from the
#previous step and the $user_data array.
$getService.stage_and_install($patchVersion,$user_data)
We can now check for the status but during installation you will very quickly get kicked off the server. You will have to log in after the reboot. So let’s look at the API again. Notice, there is no .pending. And we see there are no parameters. So this is as simple as it gets.
#We know this part, now without pending
$getService = Get-CisService -Name "com.vmware.appliance.update.pending"
#Get the status.
$getService.get()
The result would be like this. The interesting part would be the state. According to the API the state could have following values.
UP_TO_DATE: The appliance is up to date. UPDATES_PENDING: A new update is available. STAGE_IN_PROGRESS: The appliance update is in progress of downloading an update. INSTALL_IN_PROGRESS: The appliance update is in progress of installing an update. INSTALL_FAILED: The appliance update failed and cannot recover. ROLLBACK_IN_PROGRESS: The appliance update failed and recovery is in progress.
When the update started it will have “INSTALL_IN_PROGRESS”. Again, you will be quickly get kicked off the system and have to log in again. After reboot it should say “UP_TO_DATE”
$getUpdate = Get-CisService -Name “com.vmware.appliance.update”;
$getUpdate.get();
Help : @{Documentation=The {@name Info} {@term structure} describes the state of the appliance update.; state=; task=; version=; latest_query_time=}
latest_query_time : 3/24/2019 9:30:00 PM
task : @{Help=; parent=; cancelable=False; subtasks=System.Collections.Generic.Dictionary2[System.String,System.Management.Automation.PSObject]; end_time=4/2/2019
7:08:30 PM; description=; subtask_order=System.Collections.Generic.List1[System.String]; error=; target=; start_time=4/2/2019 7:07:53 PM;
service=applmgmt/update; progress=; operation=stage_and_install; user=; status=RUNNING}
state : INSTALL_IN_PROGRESS
version : 6.7.0.21000
I am not sure how /rest/appliance/shutdown translates into com.vmware.appliance.shutdown but it does. Maybe it is just something you have to remember or lookup on txusa.cloud 🙂 In the following weeks I will post one on accounts and there it is even weirder, because /appliance/local-account somehow translates to com.vmware.appliance.local_accounts. Let’s look at reboot first. So when we click on reboot we see that two parameters are needed. reason of type string and delay of type long and there are no response values.
So to reboot our code would look like this. Parameters: 5 minute delay and reason “A reboot just for the fun of it.”
[code language="powershell"]
## Connect to our VCSA first.
$cisConnection = Connect-CisServer -server vcenter.txusa.cloud
## Get the object
$shutdownAPI = Get-CisService -Name "com.vmware.appliance.shutdown"
## And execute the method to reboot.
$shutdownAPI.reboot(5,"A reboot just for the fun of it.")
[/code]
If you look at the API for poweroff it takes the same two parameters. So our code would look like this for power off.
[code language="powershell"]
## Connect to our VCSA first.
$cisConnection = Connect-CisServer -server vcenter.txusa.cloud
## Get the object
$shutdownAPI = Get-CisService -Name "com.vmware.appliance.shutdown"
## And execute the method to power off.
$shutdownAPI.poweroff(5,"Let's call it a day.")
[/code]
If we look at get. Which will give us the state of a pending request we don’t have any parameters but we have response values.
So our code would look like this.
[code language="powershell"]
## Connect to our VCSA first.
$cisConnection = Connect-CisServer -server vcenter.txusa.cloud
## Get the object
$shutdownAPI = Get-CisService -Name "com.vmware.appliance.shutdown"
## And execute the method to get the pending state information.
$shutdownAPI.get()
[/code]
And last but not least we have the code for cancel which has no parameters and no response. So I guess it will cancel whatever pending request there is.
[code language="powershell"]
## Connect to our VCSA first.
$cisConnection = Connect-CisServer -server vcenter.txusa.cloud
## Get the object
$shutdownAPI = Get-CisService -Name "com.vmware.appliance.shutdown"
## And execute the method to cancel.
$shutdownAPI.cancel()
[/code]
This weeks vRealize Orchestrator snippet will show how to get the wwpn from the HBAs of each hosts in the cluster. Input parameter is a cluster object (VcClusterComputeResource), here named cluster.
//input parameter is cluster of type VcClusterComputeResource
//First we will get an array of all hosts in the cluster
var hosts = cluster.host;
//Lets do this for each host
for each (var host in hosts)
{
//This will give us an array of all HBAs of the host
var hbas = host.configManager.storageSystem.storageDeviceInfo.hostBusAdapter;
//Lets do this for each HBA of the host.
for each(var hba in hbas)
{
//We are only interested in Fibre Channel HBAs so only do this if HBA is of type VcHostFibreChannelHba.
if (hba instanceof VcHostFibreChannelHba)
{
//This will give us the WWPN
var wwpn = hba.portWorldWideNameHex;
//Lets get the device (example vmhba1)
var device = hba.device;
//Output will be like: Hostname: myesx.txusa.cloud Device: vmhba1 wwpn: 21:00:00:26:b6:02:c1:01
System.log("Hostname: " + host.name + " Device: " + device + " wwpn: " + wwpn);
}
}
}