VSA Managed Variables, Problems, and SaaS-Friendly Solutions
Well, just one month ago, I discussed using Managed Variables, and reviewed some of the challenges with them. A current bug in VSA leaves us with the inablilty to deal with undefined Managed Variables, which means we can't use the presence or abscense of a Managed Variable to decide IF we should perform a task.
I use Managed Variables - a lot - for everything from passing arguments to our utilities to control how they function to defining local accounts and even customer licensing and configuration information for commonly deployed applications. At last count, I've got 16 Managed Variables. Nearly all of them, in fact, all but two of them, define customer-specific information that may not exist for every customer, so the ability to detect when the data is defined is crucial.
Last month, I provided a workaround that we've been using internally for almost 4 years. It's a simple SQL Query that uses two arguments - the name of the Managed Variable and a default response. It reads the Managed Variable and returns the data if its defined or the default value if it isn't. This makes it easy to detect that the default value was returned and skip the action that depends on the variable being defined. Easy-peasy! Well, that's the case if you're an on-prem user of VSA. Kaseya SaaS users have, well, let's just say "challenges".
I understand that caution is needed in a shared environment, and that allowing access to the SQL back-end, even for queries, can create great angst. We've been waiting over 6 weeks to get the query approved for our TAP instance of Kaseya SaaS so that we can certify our automation. This delay was just too much to bear, especially with SaaS users asking about our automation suite, so - it was time to dig in and find an alternate solution. The challenge was that reading an undefined Managed Variable didn't just fail, it caused the procedure where it was referenced to crash at that point! The answer came - literally - while lying awake at nignt...
"If reading an empty Managed Variable crashes the procedure, then let a different procedure crash!"
Here's the process, in a nutshell. Start by creating a procedure that assigns the Managed Variable(s) that you need to global variables:
getVariable("ConstantValue", "<InitArgs>", "global:MV_InitArgs", "All Operating Systems", "Continue on Fail")
The global Managed Variable name uses a "MV_" prefix to identify it as a Managed Variable in this example, and uses a name that makes its purpose clear. In this case, it will contain any custom arguments used by our agent initialization utility. In some cases, there are multiple Managed Variables needed, and we simply collect all of them in the same procedure - each with a unique name. One such example is an application the needs the customer's product serial number, license key, and customer ID to perform an installation.
Next, in the procedure that needs the Managed Variable(s):
getVariable("ConstantValue", "xFALSEx", "global:MV_InitArgs", "All Windows Operating Systems", "Halt on Fail")
executeProcedure("ALL-GetManagedVar-InitArgs", "", "Immediate", "All Operating Systems", "Continue on Fail")
If checkVariable("#global:MV_InitArgs#") Contains "FALSE"
executeShellCommand("CMD.exe /c RMMINIT.BMS", "Execute as System", "All Windows Operating Systems", "Continue on Fail")
executeShellCommand("CMD.exe /c RMMINIT.BMS #global:MV_InitArgs#", "Execute as System", "All Windows Operating Systems", "Continue on Fail")
This calls the first procedure with "Continue on Fail". If the Managed Variables aren't defined, that procedure fails, but does not affect the primary procedure. That procedure is able to determine that the default value is still defined and will take appropriate action. In this case, it runs the init command without passing arguments, but if the default value is not detected, it runs the init command with the arguments in the global variable. Note that the global variable is defined and set to a default value here before calling the external procedure that will reset it if the Managed Variable is defined.
I'll admit, this is a bit kludgy, but it does allow one to leverage Managed Variables on all platforms, including SaaS, without causing the primary procedure to crash.