Often you would like to customise one or two things with a script in one of the predefined workflow steps like ‘BuildingMachine’. However depending on your blueprint you do not neccessarily want to execute all of the scripts all time. Having some more dynamic selection would come in handy. This can be easily done with vCAC’s built in properties features. Here is how:
In order to have the WFStubs being run during provisioning you have to first define the respective property like ‘ExternalWFStubs.BuildingMachine’. Then depending on your need you can then change that stub workflow to either call a vCO workflow (that can easily be invoked via the new vCO plugin as described in a previous post) or you can invoke a PowerShell script directly (or of course you can do whatever you like within the workflow with one of the predefined Workflow Foundation Activities).
Maybe the easiest way is just to call a PowerShell script wrapper from either a script that you uploaded within vCAC or that you invoke from a known place like ‘C:\scripts’ (there you have to make sure that this gets replicated to all your DEM workers).
Then you have to specify what script or Cmdlet you actually want to run by creating new properties tht you link to a blueprint either directly or via a build profile like you can see in the following figure:
The wrapper script then only needs to look up the properties, construct the command line and execute the scripts. To make the whole process a little bit more flexible you can define scripts for each stage during the provisioning process (eg renaming a virtual machine does only make sense during a BuildingMachine step). In addition to defining the scripts to run you can also specify parameters as you can see in the previous figure. There you can also reference other properties or attributes of the Machine object by defining something like this: ‘#Machine.VMCreationDate’ or ‘#Machine.VMCPUs’ or any other custom property with ‘#Properties.’biz.dfch.PS.vCAC.OrderInformation.CostCenter’.
All the scripts will be checked for existence and ordered in alphabetical order. So it is best to prepend the script keys with a naming convention like ’01’, ’02’, ’03’, …
So in the example we have a script ‘Set-DomainMembership.ps1’ that accepts three parameters: ‘Domain’, ‘Username’ and ‘Password’. We use the requesting user of the machine as the ‘Username’ by specifying ‘#Machine.Owner.Username’. The password is a regular encrypted vCAC property that will be passed to the ‘Set-DomainMembership.ps1’ in an unencrypted form (check this post to get more information about encrypted properties in vCAC). The ‘Domain’ parameter is hard-coded set to ‘sharedop.org’.
The last example shows you how to specify another existing custom property that the script ‘Set-VcacVirtualMachineName.ps1’ expects as its ‘Name’ parameter: ‘biz.dfch.Machine.NewName’ is another property we defined on the blueprint that the user can either enter directly or that could be computed by some previously run scripts.
Side note: you can actually define any valid powershell expression as long as it starts with a ‘$’. This is then evaluated at run time. While this is quite powerful this is also a little bit risky. And you would certainly not let your end users or customers define these expressions.
The script actually consists of two parts: first the logic to enumerate all custom properties of relevance in the current VirtualMachineState and second to construct the command line.
In the second part we actually construct the command line to execute with all parameters defined by the various properties. We also check if the specified parameters are valid to the actual command. If not the respective parameter is skipped. The default directory where to look for the scripts is the directory where the main script is run from.
As usual error handling and logging has been reduced to a minimum to maintain readability.