I'm currently using vCAC Designer to modify the WFStubMachineProvisioned workflow to call a PowerShell script to add a DNS record.
In the script, I collect the info below, then use it later in the script to add the records. Works great.
$Hostname = $Properties["VirtualMachineName"]
$IPAddress = $Properties["VirtualMachine.Network0.Address"]
$ZoneName = $Properties["ZoneName"]
How would I go about doing this in vCO?
I do have the vCAC 6.0 extensibility package installed in vCO 5.5, but I'm new to vCO and am looking for an example of how to pull and pass vCAC VM properties in a PowerShell script.
There is a sample template which will get you started at Libraray\vCloud Automation Center\Extensibility\Workflow Template . This is a good item to duplicate and start creating your workflow. I also created this action which will pull pretty much everything I need into one properties type. Then you can just do allProps.get("whateverpropertyyouneed"); In this example I am using a call to a couple of other actions I have posted on here recently. One that gets the vCenter vm from the vCAC vm and one the gets the vCACHost from the vCACVm. This way only have to pass the action the vCACVM. For some reason neither of those things is a simple attribute of the vCACVM:VirtualMachine object type. Just look at my other recent posts and you can grab the sample code for those actions.
var allProps = new Properties();
var virtualMachineEntity = vCACVm.getEntity();
// System.log("Got vCAC virtual machine " + vCACVm.virtualMachineName);
// System.log("Matching virtual machine entity " + virtualMachineEntity.keyString);
var vCenterVm = System.getModule("com.qualcomm.basic").QCgetvCenterVmFromvCACVm(vCACVm);
var vCACVmProperties = vCACVm.getEntity().getProperties();
if (vCenterVm != null) {
// System.log("Got vCenter VM " + vCenterVm.name + ", ID: " + vCenterVm.id);
allProps.put("vCenterVm", vCenterVm);
}
//Load vCAC VM properties
if (vCACVmProperties != null) {
for each (var key in vCACVmProperties.keys) {
allProps.put(key, vCACVmProperties.get(key));
}
}
var vCACHost = System.getModule("com.qualcomm.basic").QCgetvCACHostForvCACVm(vCACVm);
var vCACVmExtendedProps = System.getModule("com.vmware.library.vcac").getPropertiesFromVirtualMachine(vCACHost,vCACVm);
//Load vCAC VM Extended properties
if (vCACVmExtendedProps != null) {
for each (var key in vCACVmExtendedProps.keys) {
allProps.put(key, vCACVmExtendedProps.get(key));
}
}
for each (var key in allProps.keys) System.log(key + ": " + allProps.get(key));
return allProps;
Thanks qc4vmware...
Can this be done with PowerShell?
Do I just take your code above and create a new action, then call that action from a workflow?
How do I pass the hostname & IP to a PowerShell script?
Do you have an example workflow you can share?
In all you'll have to create three new actions or replace the actions I am making calls to with the code itself. Yes you just create a new action with one input of type vCAC:VirtualMachine l named vCACVm, the output is type "Properties", then just cut and paste the code above as a script.
My other posts are here Get the vCAC:VCACHost from the vCAC:VirtualMachine and here get vCenter VM from vCAC VM .
As for what you can and/or can't do with PowerShell I'm not sure. If you are using a windows based vCO server and have the powershell scripts local you can easily call them using the "Command" scripting object. There is also the powershell plugin for vCO but I have never tried using that so I am not exactly sure how it is implemented. You should be able to just recreate the powershell script natively in vCO which will probably be the best option long term.
Once you create this action and run it against a vm it will spit all the properties and their values into the logs. What you will most likely want are the "hostname" and the ip address of the first nic. So the code would be:
var hostname = allProps.get("VirtualMachineName"); // using your example above... you might also want allProps.get("hostname");
var ipaddress = allProps.get("VirtualMachine.Network0.Address");
var zonename = allProps.get("ZoneName");
Then to call your powershell script something like
var psCommand = new Command("c/path/script.ps " + hostname + " " + ipaddress + " " + zonename);
psCommand.execute(true);
So poster "lmonaco" and I have been working on this one, we have a workflow that add A/PTR records to the parent zone. How do we combine the VirtualMachineName with "ZoneName" (Blueprint Custom Property with .child.domain.com)?
Working Parent Zone:
var recordName = vcacVM.getProperty("VirtualMachineName");
var vmProps = vcacVM.getLink(vcacHost,"VirtualMachineProperties");
for each (var prop in vmProps) {
var propertyName = prop.getProperty("PropertyName");
var propertyValue = prop.getProperty("PropertyValue");
if (propertyName == "VirtualMachine.Network0.Address") {
var recordValue = propertyValue;
}
}
----------------------------------------------------------------------------------------------------------------------
Would like to add "ZoneName", something like this?
var recordName = vcacVM.getProperties("VirtualMachineName"+"ZoneName");
I am still learning how to script; I get the feeling another line is needed to combine the properties right?
You need to get the VirtualMachineName and ZoneName properties and store them each in their own variable (\, once you have done that, THEN you concatenate them like:
var recordName = vmName + zoneName;
In the above example, you would have stored the "VirtualMachineName" property in the variable "vmName" and the "ZoneName" property in the variable "zoneName".
This isn’t working but I feel I am close:
var recordName = vmName + childName;
var vmProps = vcacVM.getLink(vcacHost,"VirtualMachineProperties");
for each (var prop in vmProps) {
var propertyName = prop.getProperty("PropertyName");
var propertyValue = prop.getProperty("PropertyValue");
if (propertyName == "VirtualMachine.Network0.Address") {
var recordValue = propertyValue;
var vmName = prop.getProperty("VirtualMachineName")
var childName = prop.getProperty("ChildName")
}
}
In the lines above that code, are you setting/retrieving values for "vmName" and "childName" ?
It looks like you should move that first line to the last line of code inside your If statement.... that seems to be where you are defining values for those two variables.. you can't concatenate the values until they have been assigned
var vmProps = vcacVM.getLink(vcacHost,"VirtualMachineProperties");
for each (var prop in vmProps) {
var propertyName = prop.getProperty("PropertyName");
var propertyValue = prop.getProperty("PropertyValue");
if (propertyName == "VirtualMachine.Network0.Address") {
var recordValue = propertyValue;
var vmName = prop.getProperty("VirtualMachineName")
var childName = prop.getProperty("ChildName")
var recordName = vmName + childName;
}
}
Got it working with this:
var vmName = vcacVM.getProperty("VirtualMachineName");
var recordName = (vmName + '.' + 'child-domain');
var vmProps = vcacVM.getLink(vcacHost,"VirtualMachineProperties");
for each (var prop in vmProps) {
var propertyName = prop.getProperty("PropertyName");
var propertyValue = prop.getProperty("PropertyValue");
if (propertyName == "VirtualMachine.Network0.Address") {
var recordValue = propertyValue;
}
}
Still having trouble pulling vcacVM properties like "VirtualMachine.Network0.DnsSuffix" and "ChildZone" (Custom Prop with FQDN). I didn't write the original script but managed to get this one working by adding the "." and the "child-domain" in text in the second line.
Thanks for the guidance!
Can this be adapted for vCloud vApp deployments. I am modifying the MachineProvisioned workflow and vCAC is not sending a value for the vCloudvApp In parameter. It appears I do have the vCloud:VM Object Id as a property of the vCACVmProperties.
var vcVmUuid = vCACVmProperties.get("VirtualMachine.Admin.UUID");
How can I get the vCloud:VM and then the VCVirtualMachine thta I can then take action on?
Any guidance would be appreciated.
Hello,
I am working with VCO scripting and I build a workflow.
I am trying to obtain a VCAC Virtual machine object from a VCAC Guid. All that I found in the API is this
var vCACEntity = System.getModule("com.vmware.library.vcac").getVirtualMachineEntityFromId( null, virtualMachineId );
I obtain a VCACEntity. Next I need to obtain the VCACVirtualMachine object in order to extract its extended properties.
Code would be something like this:
vCACVmExtendedProps = System.getModule("com.vmware.library.vcac").getPropertiesFromVirtualMachine(host, vCACvm);
where the vCACvm is the VCACVirtualMachine object.
I can't (don't know) to make the connection between VCACEntity and VCACVirtualMachine object.
Any hint how to do this?
much appreciated.
thanks.
Bogdan
Do
vCACvm = vCACEntity.getInventoryObject();
Thanks for that. This works indeed.
Actually what I was trying to do is to change the virtual machine name from the VCO script. This is possible with VCAC Designer workflows, but my intention is to rewrite them completely in VCO.
From another blog I got this command:
System.getModule("com.vmware.library.vcac").addUpdatePropertyFromVirtualMachineEntity(host,vCACvmEntity,'VirtualMachineName',machineName);
However this attempts to create/update a custom property named 'VirtualMachineName' which is wrong (the VM name is not custom property). After this it fails
wirth message
Create property VirtualMachineName : [MODIFIED_VMNAME] on virtualMachine entity [VMNAME]
The validated object is null (Dynamic Script Module name : addUpdatePropertyFromVirtualMachineEntity#42)
In VCAC Designer it's used the ManagementModelEntities object which is able to call the "Update" method for a VM object, combined with powershell.
example:
$Machine.VirtualMachineName = $machineName.ToUpper();
if ( $MgmtContext -ne $null ) {
$MgmtContext.UpdateObject($Machine)
$MgmtContext.SaveChanges()
}
So I am not sure if this is even possible directly from VCO scripting. I use VCAC 5.2 with VCenter 5.5
Any help or hint is much appreciated.
thanks,
Bogdan
Were you able to fully get this figured out? I want to do the same thing. I am trying to use a workflow called "create / update property on virtual machine entity" which is in essence just calling the "addUpdatePropertyFromVirtualMachineEntity" action for you. I am setting the property name to "VirtualMachine.Network0.Name" and the value is my network label. When it runs however I'm getting the error "The validated object is null (Dynamic Script Module name : addUpdatePropertyFromVirtualMachineEntity#7).
I was able to rename a virtual machine by removing and adding back the property. I didn't used anymore the "addUpdatePropertyFromVirtualMachineEntity" method but this:
var vCACvmEntity = System.getModule("com.vmware.library.vcac").getVirtualMachineEntityFromId( null, virtualMachineId );
var virtualMachineProperties = vCACvmEntity.getProperties();
var machineName = "NEW VM name";
virtualMachineProperties.remove('VirtualMachineName');
virtualMachineProperties.put('VirtualMachineName', machineName);
var hostId = vCACvmEntity.hostId;
var modelName = vCACvmEntity.modelName;
var entitySetName = vCACvmEntity.entitySetName;
var entityIdString = vCACvmEntity.keyString;
actionResult = System.getModule("com.vmware.library.vcac").updateVCACEntity(hostId,modelName,entitySetName,entityIdString,virtualMachineProperties,null,null) ;
However I am not sure if this works for every VM property or if there other unwanted consequences when removing and adding a property.