Tag Archives: REST

Automate vRealize Orchestrator with PowerShell: Introducing PowervRO

For the PowerCLI book 2nd Edition I helped put together a chapter on vRealize Orchestrator. Most of the chapter was focused on running PowerShell scripts from vRO, which was something I’d had a fair bit of experience with in projects I had been on and also thought would be what most people reading would be interested in. At the end of the chapter I added a few functions using the vRO REST API to run things in vRO from PowerShell as a bit of an after-thought.

I was quite surprised when during a review phase my co-author Brian Graf suggested swapping the content of the chapter around because he thought there might be more interest in driving vRO with PowerShell, rather than having vRO execute PowerShell scripts. That didn’t quite happen due to time constraints on the book, but I kept that thought in mind having been sparked by the interest.

While putting together PowervRA I had some thoughts about expanding on what I had done in the book around PowerShell and vRO, improving what I had done for the book based on some feedback and incorporating everything we had learnt while putting that toolkit together. Thankfully Craig was up for another project and so PowervRO was born!

Over the course of the last two months or so we have put a toolkit of PowerShell functions together covering a significant portion of the vRO REST API and thankfully it has been a lot more pleasurable than what we have experienced with PowervRA  😉

Initial Release

For the initial release we have 59 functions available covering a sizeable chunk of the vRO REST API. Compatibility is currently as follows:

vRO: versions 6.x and 7.0.1

PowerShell: version 4  and above is required.

You can get it from Github  or the PowerShell Gallery

We have provided an install script on Github if you are using PowerShell v4. If you have v5 you can get it from the PowerShell Gallery with:

Getting Started

Get yourself a copy of the module via one of the above methods or simply downloading the zip, unblocking the file and unzipping,  then copying it to somewhere in your$env:PSModulePath.



Import the module first:

You can observe the functions contained in the module with the following command:

Before running any of the functions to do anything within vRO, you will first of all need to make a connection to a vRO server. If you are using self signed certificates, ensure that you use the IgnoreCertRequirements parameter. :

You’ll receive a response, which most importantly contains an encoded password. This response is stored automatically in a Global variable: $vROConnection. Values in this variable will be reused when using functions in the module, which basically means you don’t need to get a new encoded password or server URL each time, nor have to specify it with a function – it’s done for you.

Each of the functions has help built-in, alternatively you can visit this site http://powervro.readthedocs.org

Example Use Case: Invoke a vRO Workflow with a Single Parameter

Having made a connection to vRO, it’s now time to start using some of the functions from the PowervRO module. To invoke a vRO workflow we need to determine the Id of the workflow and whether the workflow requires any parameters to be sent in order to run it correctly. Let’s look at an example of a workflow Test02.

The Id is 5af6c1fd-3d12-4418-8542-0afad165cc08


The workflow has a single parameter, a, which is a String:


The schema of the workflow is very simple, there is a single Scriptable Task which logs what the input parameter a was:



We can get the ID of a vRO workflow with Get-vROWorkflow:

and we could use that ID directly with Invoke-vROWorkflow. However, we made this easier by adding Pipeline support to Invoke-vROWorkflow, so all you need to do is this:

And here’s the result:


Example Use Case: Invoke a vRO Workflow with Multiple Parameters

So that was fine for a single parameter, but what to do if the workflow has multiple parameters? The parameter set for Invoke-vROWorkflow that we used in the previous example only supports a single parameter.

Let’s look at another example. The workflow Test03 has two inputs, a and b of different types, String and Number:


Again it has a single Schema element, which does the following:


Step forward New-vROParameterDefinition. We can use a combination of this function from PowervRO and Invoke-vROWorkflow and the Parameters parameter to submit the request to run the vRO workflow supplying multiple parameters.

To do this, create an array of parameters using New-vROParameterDefinition and supply them to Invoke-vROWorkflow:

and here’s the result of the workflow execution:


Stay tuned for more examples on using PowervRO, you can also follow @PowervROModule for updates 🙂

Querying vRO Workflows with the REST API and Multiple Conditions

Querying vRO workflows using the vRO REST API is relatively straightforward task. Use the below URL with a GET request and specify a condition to search for them, e.g. to find one by it’s name use:


You should get a response similar to the following if a workflow of that name exists:

"link": [
"attributes": [
"value": "https://vroserver.domain.local:8281/vco/api/workflows/cb9264b1-c832-4ee3-b95a-db73f7a2fedf/",
"name": "itemHref"
"value": "cb9264b1-c832-4ee3-b95a-db73f7a2fedf",
"name": "id"
"value": "Test",
"name": "categoryName"
"value": "true",
"name": "canExecute"
"value": "https://vroserver.domain.local:8281/vco/api/catalog/System/WorkflowCategory/40281e864cebecc5014cebfdd3ab0f25/",
"name": "categoryHref"
"value": "",
"name": "description"
"value": "Test01",
"name": "name"
"value": "false",
"name": "customIcon"
"value": "Workflow",
"name": "type"
"value": "true",
"name": "canEdit"
"value": "0.0.1",
"name": "version"
"href": "https://vroserver.domain.local:8281/vco/api/workflows/cb9264b1-c832-4ee3-b95a-db73f7a2fedf/",
"rel": "down"
"total": 1

I wanted to query with multiple conditions though, e.g. name and categoryName or version and categoryName. Possibly I’m not looking in the right place, but I couldn’t find any documentation or examples for the syntax of using multiple conditions:



A few attempts of trial and error revealed separating conditions with a comma is the way to go, for example:

1) Look for workflows named New-Array in the vRO folder (categoryName) Test


2) Look for workflows in the vRO folder (categoryName) Test with version number 0.0.1


Note: It’s worth bearing in mind Conditions are case sensitive, so categoryName not categoryname, otherwise the query will fail. Their associated values e.g Test or New-Array are not case sensitive.

Publish IaaS Blueprint in vRO via the vRA REST API

There is an excellent post over at Automate-IT.today which details how to create a vRA IaaS Blueprint from vRO. Once you have used the workflow from that site to create a Blueprint it still needs to be published before it can be used as a vRA Catalog Item, added to a Service etc.


Note that even updating Christiaan Roeleveld‘s code to set the property IsPublished to true, doesn’t actually publish the Blueprint. Although in the screenshot above it appears to be published, it doesn’t actually show up in Administration / Catalog Items yet.

I needed to be able to do this and found that it is possible via the vRA REST API. Check out  PUT request to “Register a ProviderCatalogItem or update an already registered one.”

1) Get an authentication token

To achieve this in vRO you will first of all need to obtain an authentication token, I detailed how to do that in a previous post.

2) Create a REST operation for Register a ProviderCatalogItem

Run the Add a REST operation workflow and populate with the REST host and PUT request details, using the URL from the above documentation: /catalog-service/api/provider/providers/{providerId}/catalogItems/{bindingId}


3) Generate a workflow for Register a ProviderCatalogItem

Run the Generate a new workflow from a REST operation workflow. Populate with the REST operation created above and set the Content type to application/json .


Give it a name and select a folder to store it in.


4) Update the generated workflow with a token input and additional headers

You’ll need to edit the Scriptable Task in the generated workflow. Add an extra input parameter of token, type string.



On the Scripting tag, add the following lines of code to include the authentication token and an Accept header:

var authorizationToken = "Bearer " + token

request.setHeader("Accept", "application/json");
request.setHeader("Authorization", authorizationToken);

5) Get the IaaS Provider ID

The observant among you will have noticed that from the PUT URL, /catalog-service/api/provider/providers/{providerId}/catalogItems/{bindingId}, we need to supply a providerId and a bindingId. The providerId for our example is the ID of the IaaS provider. This can be determined via a separate REST call.

6) Create a REST operation for Get Providers

Run the Add a REST operation workflow and populate with the REST host and GET request details for this URL: /catalog-service/api/providers


7) Generate a workflow for Get Providers

Run the Generate a new workflow from a REST operation workflow. Populate with the REST operation created above.


Give it a name and select a folder to store it in.



8) Update the generated workflow with a token input and additional headers

You’ll need to edit the Scriptable Task in the generated workflow. Add an extra input parameter of token, type string.


On the Scripting tag, add the following lines of code to include the authentication token and an Accept header:

var authorizationToken = "Bearer " + token

request.setHeader("Accept", "application/json");
request.setHeader("Authorization", authorizationToken);

Note: the response you will receive to GET providers will be something like the following. We are interested in the iaas-service id property:

 "links": [],
 "content": [
 "@type": "Provider",
 "id": "934c88ec-607e-415b-ad38-1290c30d8610",
 "name": "iaas-service",
 "providerTypeId": "com.vmware.csp.iaas.blueprint.service"
 "@type": "Provider",
 "id": "0dd55fd2-2b1a-432e-89af-b77cb6f41b15",
 "name": "Advanced Designer Service",
 "providerTypeId": "com.vmware.csp.core.designer.service"
 "metadata": {
 "size": 20,
 "totalElements": 2,
 "totalPages": 1,
 "number": 1,
 "offset": 0

9) Get the Binding ID

The other item we will need to provide is the Binding ID. Thanks to Christiaan for pointing out that this is the virtualMachineTemplateId property of the IaaS Blueprint.


10) Publishing the Blueprint

Armed with the following info, we are now able to run the New-ProviderCatalogItem workflow:

  • Authentication token
  • ProviderId
  • BindingID

We also need to send the following JSON text with the PUT request as detailed here. Replace the following values:

  • id – virtualMachineTemplateId / BindingID
  • name – Catalog Item name
  • description – Catalog Item description
  • tenantRef – vRA Tenant name
  • tenantLabel – vRA Tenant name

 "id": "357b9240-62bd-4201-9be0-b3c6180643b9",
 "name": "Centos-Small",
 "description": "Centos-Small",
 "iconId": "cafe_default_icon_genericCatalogItem",
 "catalogItemTypeId": "Infrastructure.Virtual",
 "organization": {
 "tenantRef": "Tenant10",
 "tenantLabel": "Tenant10",
 "subtenantRef": null,
 "subtenantLabel": null
 "outputResourceTypeId": "Infrastructure.Virtual",
 "forms": null

Run the workflow and enter these details:




A successful workflow run will see the blueprint published to a catalog item.



Use Headers in a vCO REST Operation

vCenter Orchestrator has a built -in plugin for working with systems that support REST API queries. I’ve used this fairly extensively recently while working with vCNS

Out of the box the plugin will do the majority of the hard work for you, however one thing that isn’t available via the Add a REST operation dialogue is the ability to configure a custom header for the REST query. In the following example I need to add an if-match header to update the App firewall rules for a portgroup, but for a POST method I only have the option to specify the Content type:


Per the vCNS API document I need to be able to send  something like the following

POST https://<vsm-ip>/api/2.0/app/firewall/dvportgroup-28/config –header ‘Content-Type:text/xml’ –header ‘if-match:”1347501121780″‘

So we need to dig a bit deeper. After creating a workflow from the REST Operation we have something like the following:


and in the Scripting task, the following code:


Luckily, (and something I hadn’t noticed before) an example for how to set a header has been added as a standard comment:

//Customize the request here
//request.setHeader("headerName", "headerValue");

So in this example we need to add the following:

request.setHeader("If-Match", generationNumber);

First of all though, we will need to add an input for the generationNumber (you can obtain the generationNumber by first of all querying the current ruleset and looking for the Etag header):


Now we can update the Scripting task:


and we can successfully add extra App Firewall Rules when using this workflow now:



vShield 5.5 API Programming Guide – Corrections


It’s pretty disappointing to need to do this, but recently while working with vCNS / vShield 5.5 and automating it via the REST API I have been making extensive use of the vShield 5.5 API Programming Guide.  On the whole its a decent document with lots of useful examples, without which I would have been struggling.

However, there are numerous mistakes in it, particularly around the URLs required for various API calls. The document doesn’t seem to have been QA’d particularly well before being released and as far as I can see many of these same mistakes are present in the 5.1 document.

Since other people seem to be wasting time finding the same type of issues, I’m documenting those I find as I go on in the hope that at least it should make it easier for people to find what’s wrong, rather than waiting for a communities post response or trial and error like I have been doing.

Those I have discovered so far are below. The documented URL is listed first, the correct one is below it.

Area Title URLs -Documented, Followed By Corrected  Page
List IPsets Created on a Scope GET https://<vsm-ip>/api/2.0/services/ipset/<scope-moref> 31
GET https://<vsm-ip>/api/2.0/services/ipset/scope/<scope-moref>
Add Service to a Scope POST https://<vsm-ip>/api/2.0/services/application/scope/<moref> 41
POST https://<vsm-ip>/api/2.0/services/application/<moref>
Get Details of a Service GET https://<vsm-ip>/api/2.0/services/applicationgroup/<applicationgroup-id> 43
GET https://<vsm-ip>/api/2.0/services/application/<application-id>
Modify Service Details PUT https://<vsm-ip>/api/2.0/services/applicationgroup/<applicationgroup-id> 43
PUT https://<vsm-ip>/api/2.0/services/application/<application-id>
Delete Service from Scope DELETE https://<vsm-ip>/api/2.0/services/applicationgroup/<applicationgroup-id>?force=<true|false> 44
DELETE https://<vsm-ip>/api/2.0/services/application/<applicationid>?force=<true|false>
Virtual Servers
Append virtual server POST https://<vsm-ip>/api/3.0/edges/<edgeId>/loadbalancer/config/virtualserver 136
POST https://<vsm-ip>/api/3.0/edges/<edgeId>/loadbalancer/config/virtualservers
Force Sync Edge Device GET https://<vsm-ip>/api/3.0/edges/<edgeId>?action=forcesync 141

If you have any of your own, please leave them in the comments and I’ll add them to the above.