It’s quite evident that vRO Workflows can grow huge for major provisioning tasks like hardware deployments, vApp deployments or tenant provisioning etc. just to name a few. And in a big environment, such workflows can come in large numbers and may be coupled with various other workflows quite generally for eg. using Nested WFs.
Concern
Now, the real pain starts when you have to debug them. for Debugging, developers relies mostly on System.log() or System.debug() to know about the statuses and variable values etc. up to a particular point, which is really great.
If I talk about myself, I even uses a start and completion log for every Scriptable task in a workflow. This always pinpoints to the scriptable task that was started but couldn’t complete due to any reason and therefore couldn’t print the end log. Let me explain it. There is a workflow (Create a VM) and there is a scriptable task (Get All VM Names). In this scriptable task, I would add some thing like
System.log("\"Get all VM Names\" script started");
and at the end of this script
System.log("\"Get all VM Names\" script completed");
Imagine this in a very large workflow, this can really help. But I knew this needs to be improved. Sometimes, you changes the content of a scriptable task and its definition changes, so update it’s name -> Get All VM Names to Get All VM Names and IPs. In such cases, you have to update those start and end log statements. And I hate that!
Possible Solution
I referred to the vRO community (link) and found one interesting way out.
This will automatically print the updated name of the scriptable task.
vRO Workflow Screenshot with scriptable tasks | Image by Author
You can also print the item# if you want, using this command
System.currentWorkflowItem().getName();
FOR ACTIONS (OPTIONAL)
Now, this is a little tricky. We can’t do the same for actions. However, if we consider them as a part of a workflow, which means they will act similarly as an item and obviously will have a item number, then we can print their start and end cycle. We can do so by adding the below mentioned script in your actions.
If you are looking for a way to quickly install plugins in your vRealize Orchestrator (.dar or .vmoapp files), you can try this Python (.py) script which uses vRO ControlCenter API at its core.
Prerequisites
Python3 installed
Download the plugin that you want to install to a local folder. For demo purpose, you can download a small plugin called JsonPath from here.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TL;DR Download the package from here & edit the inputs and run it to get a CSV Report for last 30 days of Workflow Runs in vRealize Orchestrator.
Many a times, we have environments where we want to monitor the executions of vRealize Orchestrator Workflows, like how many times a workflow is run, who executed the workflow, or what was the success rate of a particular workflow, or maybe just want to check how long it take to execute a workflow. I have seen few customers that were looking for similar solutions. So, If you are also looking for a way to achieve something similar, this article could be of some help.
As we know, vRO offers REST API out-of-the-box for all kind of operations. Same is true for getting the facts and figures of its workflow execution. There are various ways to get that kind of information but I find using the catalog-service-controller module to be the quickest for my use-case. Let’s see it in detail below.
Understand the REST API
The catalog-service-controller module is quite a versatile API module in vRO. You can use it to dig-in information for a extensive set of entities. However, the path and method we are mostly interested in today is, GET /api/catalog/{namespace}/{type}.
Namespace = System
type = WorkflowToken
/api/catalog/System/WorkflowToken?conditions=state%5Ecompleted%7Cfailed&conditions=endDate%3E"+date30DaysAgo+"&conditions=endDate%3C"+currentDate
where date30DaysAgo will get its value from getDate30DaysAgo()action and currentDate from getCurrentDateInISOFormat()action available in the vro-package.
Note You can add more states to this query like waiting, canceled, etc. if you are interested in workflow tokens other than completed and failed.
Understand the Code
In the package attached, we have a workflow Workflow Runs Report Generation which will have the code divided in 3 parts. For ease of operation, the workflow is creating a transient REST host using user provided inputs but you can also add your vRO as a REST Host in the inventory and add this REST URL as a REST Operation with dates as variable input. Also, in Part 2/3, only 5 properties are added to the CSV data. You can lookup for additional properties related to a workflow token if you want a more details-heavy report.
//Part 1/3: Invoke Rest Operation
.
.
.
//Part 2/3: Gather data in CSV format
var reportCSV = "Name,Status,Start Date,End Date,Started by\r\n";
if (response.statusCode != 200) { // 200 - HTTP status OK
System.warn("Request failed with status code " + response.statusCode);
} else {
var doc = JSON.parse(response.contentAsString);
System.log("Number of failed or cancelled tokens: " + doc.total);
for each(var link in doc.link) {
for each(var attribute in link.attributes) {
if (attribute.name == "name")
var wfName = attribute.value;
if (attribute.name == "state")
var wfState = attribute.value;
if (attribute.name == "startDate")
var wfStartDate = attribute.value;
if (attribute.name == "endDate")
var wfEndDate = attribute.value;
if (attribute.name == "startedBy")
var wfStartedBy = attribute.value;
}
reportCSV += (wfName + "," + wfState + "," + wfStartDate + "," + wfEndDate + "," + wfStartedBy+"\r\n");
}
}
//Part 3/3: Send CSV data as a mail attachment
.
.
.
In Part 3/3, we are simply attaching the CSV data as a MIME attachment and send it to the toAddress.
Let’s Run it
Import the package available here. If you need help with package import, follow this guide here.
Go to workflow Workflow Runs Report Generation and Click Edit
Go to the scriptable task and edit these input values.
After editing the values, Save it.
Click Run.
If the workflow executed successfully, you will see in the logs, the mail is being sent to the provided email address.
Check your mailbox. If you can’t see the email in your inbox, probably check the email address that you’ve provided or check your SPAM folder.
Download the attached CSV file and Open it. You will see a sheet which will be identical to what you have in your vRO Workflow Runs Tab (Performance view OFF). You may also want to sort this sheet on Start Date column in descending manner.
Download vRO Package
That’s it in today’s post. I hope you will like it.
Manipulation of Date & Time is overwhelmingly difficult. Mostly because there are so many formats, standards and handling techniques. Being a vRO programmer, you can’t run away from this date manipulation, be it for Reports creation, REST Calls, Data fetching or Interacting with other servers. Ask any programmer about their experience handling dates and time zones and they will probably share some war stories. Handling date and time fields is certainly not rocket science but can often be tedious and error-prone.
In this article, we will explore some of the key concepts that are necessary for manipulating date and time values correctly, formats that are convenient for storing DateTime values and transferring them over APIs, and more. You can consider it as a complete guide to understand the DateTime concepts in vRealize Orchestrator using the system-provided classes.
If you are sending and receiving data through a REST API, you will eventually need to convert the date to a string and vice versa because JSON doesn’t have a native data structure to represent DateTime.
Advertisements
IntrinsicDate() Class
vRO provides a Date() class to satisfy almost all the date and time hunger. It has a constructor that takes variety of inputs to start off. There are various methods and functions take allows quick shape-shifting of date and time. However, It may lack some quirky features that you may look out for. Let’s start off by taking a look at this Date class in a more comprehensive way.
It starts here. You call the constructor and you will get the current date and time. BOOM!🚀
const currentDate = new Date();
If you don’t pass anything to the Date constructor, the date object returned contains the current date and time.
You can then format it to extract only the date part as follows:
const currentDate = new Date();
const currentDayOfMonth = currentDate.getDate();
const currentMonth = currentDate.getMonth(); // Be careful! January is 0, not 1
const currentYear = currentDate.getFullYear();
const dateString = currentDayOfMonth + "-" + (currentMonth + 1) + "-" + currentYear;
System.log(dateString)
//Output = "19-03-2022"
Caution It’s not getYear(), but getFullYear()
If you instead want to get the current time stamp, you can create a new Date object and use the getTime() method.
Tip In JavaScript, a time stamp is the number of milliseconds that have passed since January 1, 1970, which is also known as Unix/ECMAScript Epoch format.
You can also take an input of Type Date in workflow or action and handle it in your scripts just like any other Date object.
Parsing a Date
Converting a string to a JavaScript date object is done in different ways.
The Date object’s constructor accepts a wide variety of date formats:
const date1 = new Date("Wed, 27 July 2022 13:30:00");
const date2 = new Date("Wed, 27 July 2022 07:45:00 UTC");
const date3 = new Date("27 July 2022 13:30:00 UTC+05:30");
or we can also use Date.parse(), that will return timestamp as string
var ms = Date.parse("27 July 2022 13:30:00 UTC+05:30");
System.log(ms); // 1469605500000 (timestamp)
Note that you do not need to include the day of week because JS can determine the day of the week for any date.
You can also pass in the year, month, day, hours, minutes, and seconds as separate arguments:
const date = new Date(2022, 6, 27, 13, 30, 0);
or you can even pass the Unix Epoch number directly:
const date = new Date(1647678776796);
that means to get the zeroth timestamp i.e. Jan 1st of 1970 UTC+0, pass 0 as a parameter to Date()
const date = new Date(0);
or you can also use System.getDateFromFormat() to convert a string to Date object. Check more here.
d = System.getDateFromFormat("2019-01-01T01:45:00.100", "yyyy-MM-dd'T'HH:mm:ss.SSS");
System.log(d);
Advertisements
Working withISO 8601 Format (YYYY-MM-DDTHH:mm:ss.SSSZ)
Of course, you can always use this specific ISO date format:
const date = new Date("2022-07-27T07:45:00.000Z"); // Fri Sep 02 2022 07:45:00 GMT-0000 (GMT)
Get Current Date in ISO complete format
Many a times, we need Dates in a complete ISO format [YYYY-MM-DDTHH:mm:ss.SSSZ], for making REST calls etc. We can use the toISOString() or toJSON() methods of the Date object to convert the local DateTime to UTC.
If you are sure of the format you want to use, it is best to extract individual bits using the JavaScript functions we covered above and create a string yourself.
var currentDate = new Date();
var date = currentDate.getDate();
var month = currentDate.getMonth();
var year = currentDate.getFullYear();
We can get the date in MM/DD/YYYY format as
var monthDateYear = (month+1) + "/" + date + "/" + year;
The problem with this solution is that it can give an inconsistent length to the dates because some months and days of the month are single-digit and others double-digit. This can be problematic, for example, if you are displaying the date in a table column, because the dates don’t line up.
We can address this by using a “pad” function that adds a leading 0.
function pad(n) {
return n<10 ? '0'+n : n;
}
Now, we get the correct date in MM/DD/YYYY format using:
By now, you might understand how to get bits of information out of dates and how to pad them. Now, let’s create an ISO format from scratch like I have done here (contains +00:00 instead of Z as per my requirement).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Get the number of seconds since the Unix/ECMAScript Epoch
var seconds = Math.floor(Date.now() / 1000);
Working with past and future dates
The best way to work and calculate present and future dates is by using Unix Epoch format which is conveniently the number of milliseconds after midnight January 1, 1970 till the given date expressed as a string which is IETF format. Let’s see few examples.
Important It should be noted that the maximum Date is not of the same value as the maximum safe integer (Number.MAX_SAFE_INTEGER is 9,007,199,254,740,991). Instead, it is defined in ECMA-262 that a maximum of ±100,000,000 (one hundred million) days relative to January 1, 1970 UTC (that is, April 20, 271821 BCE ~ September 13, 275760 CE) can be represented by the standard Date object (equivalent to ±8,640,000,000,000,000 milliseconds).
Get current time in milliseconds
// vRO System method
System.getCurrentTime() //1647861957381
//or
//Javascript method
Date.now() //1647861957381
//or
var date = new Date(); //allows any Date to be used
System.log(date.valueOf()); //1647861957381
Lets say you want to fetch the date 4 days later relative to today, you can convert the today’s date in Unix Epoch format and add 4 x 24 x 60 x 60 x 1000 milliseconds to it and you will get a date exactly 4 days ahead with same time of the day, that because you have not changed enough milliseconds to modify the time.
var date = new Date(); //Thu Mar 21 2022 11:42:06 GMT-0000 (GMT)
System.log(date.valueOf());
var frameOfTime = date.valueOf() + (4*24*60*60*1000);
var date = new Date(frameOfTime); //Thu Mar 25 2022 11:42:06 GMT-0000 (GMT)
Now, let’s say you want to go back in time 4 hours back, You will subtract 4 x 60 x 60 x 1000 milliseconds.
var date = new Date(); //Thu Mar 21 2022 11:42:06 GMT-0000 (GMT)
var frameOfTime = date.valueOf() - (4*60*60*1000);
var date = new Date(frameOfTime); //Thu Mar 25 2022 07:42:06 GMT-0000 (GMT)
Advertisements
Comparing Dates
First, we need to create date objects. Fortunately, <, >, <=, and >= all work. So comparing July 19, 2014 and July 18, 2014 is as easy as:
const date1 = new Date("July 19, 2022");
const date2 = new Date("July 28, 2022");
if(date1 > date2) {
System.log("First date is more recent");
} else {
System.log("Second date is more recent");
}
Checking for equality is trickier, since two date objects representing the same date are still two different date objects and will not be equal. Comparing date strings is a bad idea because, for example, “July 20, 2022” and “20 July 2022” represent the same date but have different string representations. The snippet below illustrates the first point:
This particular case can be fixed by comparing the integer equivalents of the dates (their time stamps) as follows:
date1.getTime() == date2.getTime();
Moreover, vRO is not very good with timezones. So, the best is that we should ignore the user’s time zone and use UTC while creating the date object. There are two ways to do it:
Create an ISO formatted date string from the user input date and use it to create a Date object. Using a valid ISO date format to create a Date object while making the intent of UTC vs local very clear.
const userEnteredDate = "12/20/1989";
const parts = userEnteredDate.split("/");
const userEnteredDateISO = parts[2] + "-" + parts[0] + "-" + parts[1];
const userEnteredDateObj = new Date(userEnteredDateISO + "T00:00:00.000Z");
const dateFromAPI = new Date("1989-12-20T00:00:00.000Z");
const result = userEnteredDateObj.getTime() == dateFromAPI.getTime(); // true
This also works if you don’t specify the time since that will default to midnight (i.e., 00:00:00Z):
const userEnteredDate = new Date("1989-12-20");
const dateFromAPI = new Date("1989-12-20T00:00:00.000Z");
const result = userEnteredDate.getTime() == dateFromAPI.getTime(); // true
Remember: If the date constructor is passed a string in correct ISO date format of YYYY-MM-DD, it assumes UTC automatically.
JavaScript provides a neat Date.UTC() function that you can use to get the UTC time stamp of a date. We extract the components from the date and pass them to the function.
const userEnteredDate = new Date("12/20/1989");
const userEnteredDateTimeStamp = Date.UTC(userEnteredDate.getFullYear(), userEnteredDate.getMonth(), userEnteredDate.getDate(), 0, 0, 0);
const dateFromAPI = new Date("1989-12-20T00:00:00.000Z");
const result = userEnteredDateTimeStamp == dateFromAPI.getTime();
System.log(result); //true
Finding the Difference Between Two Dates
A common scenario you will come across is to find the difference between two dates.
We discuss two use cases:
FINDING THE NUMBER OF DAYS BETWEEN TWO DATES
Convert both dates to UTC time stamp, find the difference in milliseconds and find the equivalent days.
const dateFromAPI = "2022-02-10T00:00:00.000Z";
const now = new Date();
const datefromAPITimeStamp = (new Date(dateFromAPI)).getTime();
const nowTimeStamp = now.getTime();
const microSecondsDiff = Math.abs(datefromAPITimeStamp - nowTimeStamp);
// Math.round is used instead of Math.floor to account for certain DST cases
// Number of milliseconds per day =
// 24 hrs/day * 60 minutes/hour * 60 seconds/minute * 1000 ms/second
const daysDiff = Math.round(microSecondsDiff / (1000 * 60 * 60 * 24));
System.log(daysDiff); //2231
FINDING USER’S AGE FROM THEIR DATE OF BIRTH
Note: We have a non-standard format. Read the API doc to determine if this means 12 Oct or 10 Dec. Change to ISO format accordingly.
You can use these logics to get more purposeful result. You can calculate the execution time of a function you just created and may optimize it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vRO does provide various methods to represent date and time in various formats out-of-the-box. Let’s have a look on their output.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vRO provides great bit of logs out-of-the-box, but the problem is, it’s not aesthetically pleasing. Frankly, these long trials of data and time [2022-03-14 02:33:03.144 -04:00INFO] annoys me a lot. If you too don’t want that annoyance or you want to show these logs to someone in most tidiest way, or maybe you simply want to preserve an action results or workflow execution, then probably you can use this trick. Let’s see how I did it.
I think the simplest way would be to find a Regex that removes it all the clutter in one go.
Solution
After execution of a workflow or action, copy the logs and open Notepad++.
Press CTRL + H. It will open Replace Tab.
In Find what field copy the below mentioned RegEx and In Search Mode, enable Regular Expression and tick Wrap around.
Important To use bots in Google Chat, you must use a work or school account.
Objective
How about building a Chatbot that brings your vRealize Orchestrator services and resources right into Google Chat, letting users get vital bits of information without leaving the conversation. That would be great, right? Why Chat you may ask if you already have Gmail? I would say because Chat is more intuitive, simple, integrated and fun-to-watch😉. And it doesn’t require any SMTP configuration to be done in vRO.
Potential Use-cases
Notifications of successful Workflow Executions on Google Chat Team Spaces
Error Notifications and auto-assignments to team member using @mention
Daily Reports and Validations on Team Spaces
and so many possibilities…
Using Incoming webhooks
Incoming webhooks let you send asynchronous messages into Google Chat from applications that aren’t bots themselves. For example, you can configure vRealize Orchestrator to notify personnel on Google Chat when a particular server goes down. Incoming webhooks serve as a quick and easy way to integrate with existing workflows such as these without the overhead of writing entire bot applications. This is the path for low-effort integrations that provide information feeds or alerts. Let’s dive into the whole process of building a chatbot using webhooks that triggers via vRealize Orchestrator.
Check action named sendNotificationsToGoogleChat. This action will be used to send notifications to Google Chat.
Run the action and pass webhookURL without https://chat.googleapis.com and a test message. (If you need to find the URL again, go to the Google Chat space, select Manage webhooks, and then copy the URL associated with your incoming webhook.)
If everything is OK, you should see this message in your space.
Step 3: Use sendNotificationsToGoogleChat action in Workflows
To utilize this action, we have to attach it in workflows for automatic notifications. Let’s take a scenario where we want to notify the team when the workflow is failed.
Create a new workflow Demo Workflow – Chatbot and add a scriptable task that will fail.
Add a Default error handler item and an scriptable task and the action sendNotificationsToGoogleChat.
In this new scriptable task, copy-paste this JS script with webhookPath that you have copied from your space.
webhookPath = "/v1/spaces/........";
message = "Important message for <users/all>: The workflow *";
message += workflow.rootWorkflow.name;
message += "* has been failed";
Add a error variable and add it to Exception Handling in all the workflow items
Time to run, Click Run and wait for it to fail.
Check your space. There should receive a message.
Tip Find this workflow in the package for testing purposes.
Limits and considerations
As you configure webhooks, take note of these limits and considerations:
If only select organizational units (OUs) in your domain have bots enabled, incoming webhooks created in a space will fail with the following error:
{ "error": { "code": 403, "message": "The caller does not have permission", "status": "PERMISSION_DENIED" } }
Incoming webhooks do work in direct messages, but only when all users have bots enabled.
Because Manage webhooks is only available from a web browser, webhooks must be set up from the Chat web app. Webhooks are not configurable from the Chat mobile app.
Text Message Formatting Guide
This section describes how to create simple messages that appear inline as if typed by a user. The is basically the message that we are passing to our vRO action.
Basic unformatted messages
Any message in Google Chat is represented as a JSON object. A basic message that specifies just a simple plaintext body could look like the following:
{ 'text': 'Your workflow "Create Egde Gateway" has successfully executed'}
If posted into Google Chat (e.g. via incoming webhooks), it would look like the following:
Using formatted text in messages
Google Chat lets you add basic formatting to the message text, including bold, italic, and strikethrough. To format text, wrap it with the following symbols:
Format
Symbol
Example
Result
Bold
*
*hello*
hello
Italic
_ (underscore)
_hello_
hello
Strikethrough
~
~hello~
hello
Monospace
` (backquote)
`hello`
hello
Monospace block
“` (three backquotes)
“` Hello World “`
Hello World
For example, consider the following JSON:
{'text' : 'Your workflow *has successfully executed*!\nCustomer created with id: _A21347-VPC_'}
This places a message like this into the Chat space:
Including links in message text
If you include a plain link URL in your message text, such as http://example.com/foo, Google Chat uses this as the link text and automatically hyperlinks that text to the specified URL.
To provide alternate link text for your link, use the following syntax:
vRealize Orchestrator server must be able to verify their identity, to communicate with other servers (vCenter Server, relational database management system (RDBMS), LDAP, Single Sign-On, and other servers) securely. For this purpose, you might need to import the SSL certificate of the remote entity to the Orchestrator trust store.
To trust a certificate, you can import it to the trust store either by establishing a connection to a specific URL, or directly as a PEM-encoded file.
Copy the text from the -----BEGIN CERTIFICATE----- to the -----END CERTIFICATE----- tag to a text editor and save it as a file in your local system.
Step 2: Import a PEM-encoded file
We can use either of the following ways for this purpose.
Control Center
vRO Library Workflow
via Control Center
Log in to Control Center as root.
Go to the Certificates page.
On the Trusted Certificates tab, click Import and select the Import from a PEM-encoded file option.
Browse to the certificate file and click Import.
via vRO Workflow
Log in to vRO Portal.
Go to Workflows under Library > Configuration > SSL Trust Manager.
Run workflow Import a trusted certificate from a file
Browse to the certificate file and click Run.
The workflow should be successfully completed.
Results
You have successfully imported a remote server certificate to the Orchestrator trust store. You can check an entry for the corresponding server in the Control Center Certificates Tab or try running the workflow related to the server for which the certificate was imported. You won’t see this error anymore.
It’s always been hard to find a way to document vRO Workflows whether working on large VMware Automation environments or be it your personal projects. I was quite anxious about it as well and tried to find some easy way to do it.
Then, one day I found a PS script by Jose Cavalheri & Michael Van de gaer where they were trying to get JS actions and configuration elements out of an unzipped vRO Package. It was quite helpful and I used it as a building block for my project that I will be talking about today. I also used export-package mechanism by Burke Azbill and some bits of vROIDE by Garry Hughes.
So before we start, let me tell you that if you want to make this functionality to work in your project, you should think of moving your code to vRO actions as much as possible.
vRO Actions are much more flexible in terms of their usage outside of vRO. As you might know, vRO uses XML based approach to save both workflows and actions. However, due to the varied nature of workflows that can contain almost anything in any format makes them convoluted. Actions on the other hand, not only have a defined scope (takes inputs and return one output) but also much easier to use in vRO as well as they provide code reusability. I know, Not everything in vRO can be and should be converted to vRO actions BUT THAT’S OK. We can deal with it. I would recommend to move to action based approach for anyone working on vRO.
Ultimately, Our objective is to document most of our code and custom APIs that we have created in form of actions.
What is vRODoc?
It is mostly a PowerShell script that connects with your vRealize Orchestrator to fetch a package that contains all your action modules and action items, intelligently add JSDoc annotation to those action items and convert them into html pages which can be presented as a web-based code documentation. See a live example here. You can also add other JSDoc comments to your actions. Learn more about JSDoc comments here.
How to get started?
Please understand this flow to get started.
FlowChart of vRODoc
Steps to follow
A Quick demo on how to create a Github Pages based website that documents all your vRO actions.
Create a package in vRO which will be used to fetch the code-to-be-documented.
Using REST, add action modules to your package using this API
Edit local copy of your vrodoc_script.ps1 to set your environment parameters
Execute this ps1 file. It may take few minutes depending on package size.
In your export path, you will notice 1 .zip file and 1 folder with your package-name.
Inside package folder, a folder “Actions” will be created with all the converted JSDoc annotated vRO Actions.
By now, you have successfully created your website. Inside package folder, go to docs folder and open index.html
Now, its time to push the content of docs folder to your repository (can be Github.com, Gitlab .com or Gitlab Self-Hosted) – I will take example of Github.com
Assuming the repo already exists in your github account, push it to your repo
Go to Settings > Pages and select Branch: main and folder/: docs and wait for few minutes for website to load on Github Pages
If you reading this line, I hope you like this article. This whole process executes from a Powershell script that can be scheduled nightly or something on one of your machine to see the latest documentation next day.
Future Scope
I am also working on making it executable from Github or Gitlab runners. That could be tricky and highly environment specific but will give it a try soon. Stay tuned.
Imagine you got a locked AD account and you don’t have access to Active Directory or don’t have rights to unlock your account but luckily have access to vRO or your colleague has access to the same vRO where your account’s AD is connected or maybe you just want to check and unlock an AD user account programmatically in your use-case (for eg. some service accounts that get locked every time you try to run something), What you should do? Just run a simple vRO script.
Solution
Create action and add input of type AD:User and paste 👇 script & execute it.
Go to API Keys to create a API Key to be used later.
Click Create and provide Key Name = script_name and glob pattern = *
Now, I have my script ready with me. However, before uploading the script, I must add some metadata to my script like Author, Description, Version etc.
For that, I have used New-ScriptFileInfo method. I put the values as per my need and run them inside Powershell console.
$Parms = @{
Path = "C:\Users\mayank.goyal1\Downloads\scriptInfo.ps1"
Version = "2.1.0"
Author = "Mayank Goyal"
Description = "This script converts vRO Package directly into JSDoc website by connecting to vRO. Requires nodejs and jsdoc module installed. Create new files *.html & *.js directly from vRO with JSDoc annotation. It consumes a package name which should exist in vRO with all the Actions you want to document and creates .js files with JSDoc Annotations."
ProjectUri = "https://github.com/imtrinity94/vRODoc"
}
New-ScriptFileInfo @Parms
Get-Content -Path C:\Users\mayank.goyal1\Downloads\scriptInfo.ps1
This creates a new file C:\Users\mayank.goyal1\Downloads\scriptInfo.ps1. Opening this file show me this content.
<#PSScriptInfo
.VERSION 2.1.0
.GUID 7202df73-3b8c-4616-adeb-b6d9b97a63c7
.AUTHOR Mayank Goyal
.COMPANYNAME
.COPYRIGHT
.TAGS
.LICENSEURI
.PROJECTURI https://github.com/imtrinity94/vRODoc
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
.PRIVATEDATA
#>
<#
.DESCRIPTION
This script converts vRO Package directly into JSDoc website by connecting to vRO. Requires nodejs and jsdoc module installed. Create new files *.html & *.js directly from vRO with JSDoc annotation. It consumes a package name which should exist in vRO with all the Actions you want to document and creates .js files with JSDoc Annotations.
#>
Copy this file’s content and put it on top of your original script.
Now, it’s time to publish our file. Use Publish-Script command along with file path and API key that I have handy already.