In vRA 6.2, using vRO 6.0, you may find that the data collection and other vRO workflows fail with the error “You must have at least one properly configured vCenter Orchestrator endpoint that is reachable”. The IaaS/Monitoring/Log will show which DEM worker threw the error. When you check the DEM worker logs for that instance, if you find the message “Could not create SSL/TLS secure channel. —> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel“, you have probably been affected by VMKB 2123455 and MS KB 3061588.
Although both articles seem to suggest that removing the offending patch will solve the problem, I think figuring out exactly which patch is rather awkward. The easier fix is to apply a quick registry hack to your DEM workers (and wherever the vRA Designer runs).
Logon as an account with admin rights (suggest the account your IaaS services run under)
Add/update the DWORD value ClientMinKeyBitLength and set the value to 512 decimal (200 hex)
Restart the DEM worker service
The Microsoft patch sets the default minimum group size to 1024. It appears that the vRO 6.0.x appliances use something less than that. This registry hack indicates that SCHANNEL should accept keys as small as 512 bits. I suggest only applying this to the necessary and affected machines since it does lower the bar for the DHE security requirements.
Thanks to Zach Milleson for reminding me that this workaround may not resolve everyone’s issue, depending on which MS patches are installed. If this workaround doesn’t work for you, you may have to locate and remove the offending patch. YMMV.
In part 1, we configured the Machine Prefix, Property Dictionary and layout to accommodate our change. In part 2, we created and saved a powershell script to create the desired machine name from the inputs we provided. In part 3, we’ll modify the Building Machine workflow stub to create and assign a new machine name. We’ll be using the vCAC Designer, so make sure you have it installed and accessible.
Launch the vCAC Designer, Load the WFStubBuildingMachine workflow from the list.
In the “Building Machine Workflow” try/catch loop, double-click the “Building Machine” flowchart to expand it. Now, locate a double-click on the “Custom Code” flowchart to expand it. The Breadcrumb should read WFStubBuildingMachine > Building Machine Workflow > Building Machine > Custom Code
At the bottom of the designer pane, click “Variables” to display and add variables to this flowchart. Add the following variables to the Custom Code scope:
Did you notice that “mgmtContext” variable that was already in there? We’re going to use that later.
From the DynamicOps.Cdk.Activities pane, drag the “GetMachineName” object to the Custom Code flowchart box. Select/highlight it and in the properties pane, set the “Machine Id” value to VirtualMachineId, Set the Machine Name value to vmName
Again from the DynamicOps.Cdk.Activities pane, drag the “GetMachineProperty” object to the Custom Code flowchart box. Select/highlight it and in the properties pane, set the “Machine Id” value to VirtualMachineId, set the PropertyName to "VMware.VirtualCenter.OperatingSystem", set the PropertyValue to vmwareOS, leave IsRequired empty. I also set the DisplayName to GetVMwareOS because we’ll use several of the GetMachineProperty activities and need to be able to tell them apart.
Once again from the DynamicOps.Cdk.Activities pane, drag another “GetMachineProperty” object to the Custom Code flowchart box. Select/highlight it and in the properties pane, set the “Machine Id” value to VirtualMachineId, set the PropertyName to "custom.machineRole", set the PropertyValue to machineRole, leave IsRequired empty. Set the DisplayName to GetMachineRole so we can tell at a glance what it’s doing.
Drag the “InvokePowershell” activity to the Custom Code flowchart box, under the GetProperty activities.. Just like previously, select/highlight it and populate the properties on the right. This activity has several more properties than the others, but we’re only going to be using a few. First, check the “IsScript” box to indicate that the CommandText value points to a PowerShell script. Then, set the Commandtext value to the path (in quotes) to the PS script you saved on the IaaS Server; "C:\scripts\CreateNewMachineName.ps1". Lastly, click the ellipsis button beside PowerShellVariables to set them. Add the following PowerShell Variables (these should look familiar, from Part 2):
Click Ok to save the Powershell Variables
From the “Primitives” section of the toolbox, drag “Assign” to the custom code flowchart box, under or beside the InvokePowershell action. Admittedly, this thing is somewhat confusing. It’s used to instantiate an object from the database for manipulation. You cannot just update the MachineName property in the request, you have to pull the machine object out, set the property on the object, then push the updated object back into the database. So, select/highlight your “Assign” statement object and set the “To” property to machine and the “Value” property to mgmtContext.VirtualMachines.Where(Function (vm) vm.VirtualMachineID = virtualmachineId).FirstOrDefault()Thanks to Tom O’Rourke for that LINQ query!
Drag another “Assign” statement next to the first. This one will be used to assign the value from our PowerShell script to the virtualmachinename property of the machine object. So, set the “To” property to machine.virtualmachinename and the “Value” to PowerShellOutVar
(Almost done) From the “DynamicOps.Repository” section of the toolbox, drag an “UpdateObject” activity object to the Custom Code area. Just as before, select/highlight it. Set “DataServiceContext” to mgmtContext. Set “Instance” to machine. That’s it.
Also from the “DynamicOps.Repository” section of the toolbox, drag a “SaveChanges” activity object to the Custom Code area. Just as before, select/highlight it. Set “DataServiceContext” to mgmtContext
Link it up! Use the tabs that appear on the side of the objects to connect them in the following order: Start -> GetMachineName -> GetVMwareOS -> GetMachineRole -> InvokePowerShell -> Assign (machine) -> Assign (machine.virtualmachinename) -> UpdateObject -> SaveChanges
Click “Send” to save your updated version of the workflow to the database
Background: When provisioning a Windows VM using the Clone Workflow and a vSphere customization specification that joins the computer to an active directory domain, the computer object is placed in the “Computers” container. I want to change that. 🙂
Modify the built-in Stub workflow to execute a Powershell script that moves the computer object based on the Business Group.
Created a new Build Profile with the ActiveDirectoryCleanupPlugin, MiscellaneousVrmProperties, RemoteDesktopProtocolProperties and VMwareWindows2008R2_64Properties Property Sets.
Created a new Windows 2008 R2 VM from a vSphere template, did not power-on. Took a snapshot
Created a new shared vSphere Linked Clone Blueprint, included a customization specification that joins the machine to the domain
Created a Business Group, Created a reservation for them, entitled the Business Group to the service and catalog item for the Windows Server
Tested requesting a new machine, it was provisioned, sysprepped and joined the domain correctly. I was annoyed that the computer object was in the “Computers” container.
Installed the VMware vCloud Automation Center Designer (found at https://your-vcac-server:5480/i) on the IaaS Server.
Installed Active Directory module for Windows PowerShell part of RSAT on the IaaS Server
We’ll need to indicate where we want the Computer Object moved to, so we’ll add that property. Since I wanted all of my Business Group’s computer objects in the same place, I added a property named targetOU to the Business Group and assigned the distinguishedName of the OU.
This script will write out our variables to a text file, so we can verify that they’re getting passed correctly. Then it performs the move. Please note that this will be executed by the DEM, so make sure the execution account has permissions to perform this action in AD.
Launch the vCAC Designer, Load the WFStubMachineProvisioned workflow from the list
In the “Machine Provisioned” try loop, locate and double-click on the “Custom-Code” item.
From the toolbox, under DynamicOps.Cdk.Activities, drag the GetMachineName element into the Custom Code box
From the toolbox, under DynamicOps.Cdk.Activities, also drag the GetMachineProperty and InvokePowerShell elements into the Custom Code box, near GetMachineName
Drag a connection from one of the “tabs” on the Start element to the GetMachineName element, from GetMachineName to GetMachineProperty and from GetMachineProperty to InvokePowerShell
While still in the Custom Code element, click “Variables” (near the bottom), click Create Variable and enter vmName for the name, leave the variable type as String. Repeat with a variable named targetOU. These are going to hold the values we want to work with through the workflow.
Select the GetMachineName element. On the Properties pane to the right, enter VirtualMachineId in the MachineId field. In the MachineName field, enter vmName. Ok, so where do these come from?! If you click on “Arguments” while in the GetMachineName element, you’ll see two, VirtualMachineId and ExternalWorkflowId. These are standard internal values that are used in these external workflows. So, we’re providing the VirtualMachine Id GUID to the system to look up the Virtual Machine Name. The “vmName” value is the name of the variable we assigned a moment ago and the GetMachineName element enters the retrieved Name into the vmName variable.
Now select the GetMachineProperty element and work with its properties. Just like before, set the MachineId to VirtualMachineId. Here, we want to retrieve the value in the “targetOU” property and set it in the targetOU variable. So set the PropertyValue to targetOU without quotes and the PropertyName to "targetOU" WITH QUOTES.
Select the InvokePowerShell element. Notice there are several more properties in with this one – don’t worry, we’re only going to use a few. In my case, I chose to use a PS script instead of a one-liner. This way, I could modify the script without modifying the workflow. So, check the box labelled “IsScript” and set the CommandText to the full path of the PS script in quotes. In this case, use "C:\scripts\movecomputer.ps1".
Our script expects two variables to be provided; $vmName and $targetOU, so click the ellipsis beside PowerShellVariables. Click Create Argument to add a new variable. Set the name to vmName, leave the direction as In and the type as String, set the value also to vmName” no quotes. Repeat for targetOU. Here, we’re telling it to create PowerShell Variables and set their values to the values of the workflow. Click Ok
Click “Send” to upload the modified workflow to the Model Manager. Now that we’ve created the workflow, we need to make sure it fires when we want it to.
Back in vCAC Infrastructure, modify the Windows blueprint by adding a property named ExternalWFStubs.MachineProvisioned. No value needed. This way, when this shared blueprint is used by any Business Group, the computer object will be moved to
the OU given in the Business Group’s targetOU property.
When an entitled member of Business Group 1 requests a VM from the Windows 2008 R2 catalog item, the VM is correctly created as a linked clone, assigned an IP address from the network profile and its Computer Object moved as expected.
I probably should have broken this into multiple parts…
I would still be twiddling my thumbs if it weren’t for the following enormously helpful bloggers: