Hi All,
I am having trouble performing some tasks in PowerCLI that I can do easily in the GUI.
Firstly, in the vCloud Director GUI, I can create a new vApp from a template that has one machine in it. I can also do that task from PowerCLI with something like the following code:
Connect-CIServer -server x.x.x.x -user ***** -org org-development -Password *****
$myVappName = 'TestApp03'
$myTemplate = Get-CIVAppTemplate -Name 'vWin2012-Template'
$myOrgVdc = Get-OrgVdc -Name 'vOrgDevelopment'
New-CIVApp -Name $myVappName -Description "Testonly." -OrgVdc $myOrgVdc -VAppTemplate $myTemplate
If I want to add some more VM's to this newly create vApp 'TestApp03', I can do it easily in the vCloud Director web GUI by browsing to the Virtual machines for the vApp, then on the actions click "add VM". I can then add several more copies of the VM from the template.
My problem is how do I perform this same action in PowerCLI ? How to add more machines from an existing template into an existing vApp ?
I want to only use "CI" type cmdlets and avoid having to "Connect-VIServer".
The version of PowerCLI that I have installed is "VMware-PowerCLI-5.5.0-1295336.exe"
Any insights or assistance is greatly appreciated.
Hi,
We are looking to do the same thing. I tried to use the re-compose option but got an error with the following code:
$vmstoaddnames = "Machine1,Machine2"
$vmstoaddnames = $vmstoaddnames -split(",")
$civapp = get-civapp "Dean Test"
$cat = Get-CIVAppTemplate "Build 29.08"
$vmstoadd = $cat.ExtensionData.Children.Vm |? { $vmstoaddnames -contains $_.name }
$refstovmstoadd = $vmstoadd | % {
$ref = new-object vmware.vimautomation.cloud.views.reference
$ref.href = $_.href
$ref
}
$recomposeparams = new-object vmware.vimautomation.cloud.views.recomposevappparams
$recomposeparams.CreateItem = $refstovmstoadd
$recompose = $civapp.extensiondata.recomposevapp_task($recomposeparams)
}
Exception setting "CreateItem": "Cannot convert the "VMware.VimAutomation.Cloud.Views.Reference" value of type
"VMware.VimAutomation.Cloud.Views.Reference" to type "VMware.VimAutomation.Cloud.Views.Vm"."
At line:8 char:1
+ $recomposeparams.CreateItem = $refstovmstoadd
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
Any help would be appreciated....
Here is a script that I used to add a VM to a vApp. You would like to trim the parts that you probably don't need (networking, computer name) and probably refine it. Reading it backwards might be easier.
####################
# Creates a VM in a specified vApp. The VM is cloned from a VM template.
# The VM is attached to an Org/VApp Network and its IP is configured.
# Author: Atanas Dimitrov Atanasov (adatanasov@vmware.com)
####################
param(
$vappName, # The name of the vApp where the workers are added
$templateVAppName, # The name of the vApp template where the worker template is stored
$templateVmName, # The name of the worker VM template
$orgNetName, # The name of the Org network that the worker VM should be connected to.
$newVMName, # The name of the newly created worker VM
$compName, # The computer name of the newly created worker VM
$ipAddress, # The IP address of the newly created worker VM
$powerOn = $false) # Set to true if you wish to have the newly created worker VM be powered on
if(!$vappName) { throw "VApp name is required" }
if(!$templateVAppName) { throw "Template VApp Name is required" }
if(!$templateVmName) { throw "Template VM name is required" }
if(!$orgNetName) { throw "Org Network name is required" }
if(!$compName) { throw "Computer name is required" }
if(!$newVMName) { throw "The new VM name is required" }
if(!$ipAddress) { throw "IP address is required is required" }
# Get API views to the target vApp, the template VM
$vapp = Get-CIVApp $vappName
$vappView = $vapp.ExtensionData
$vmTemplateRecord = Search-Cloud -QueryType "vm" -Name $templateVmName -Filter "IsVAppTemplate==True;ContainerName==$templateVAppName"
$vmTemplateView = Get-CIView -Id $vmTemplateRecord.Id
# Get the network name in the template VM and the target vApp
$netConfigSection = $vappView.Section | where { $_ -is [VMware.VimAutomation.Cloud.Views.NetworkConfigSection] }
if(!$netConfigSection) { throw "NetworkConfig section not found for the target vApp. Check that the vApp has a vApp/Org network defined." }
$netConfig = $netConfigSection.NetworkConfig | where { $_.Configuration.ParentNetwork.Name -eq $orgNetName }
if(!$netConfig) { throw "A network with name '$orgNetName' was not found in the target vApp. Check that the vApp has a vApp/Org network named '$orgNetName'." }
$netConnectionSection = $vmTemplateView.Section | where { $_ -is [VMware.VimAutomation.Cloud.Views.NetworkConnectionSection] }
# Assuming 1 network in VM template!!!
$netConnection = $netConnectionSection.NetworkConnection[0]
# Define the network settings of the newly created VM by coping the
# configuration of the template VM and changing the configuration to Static IP.
[VMware.VimAutomation.Cloud.Views.NetworkConnection] $newNetConnection = New-Object VMware.VimAutomation.Cloud.Views.NetworkConnection
$newNetConnection.Network = $netConnection.Network
$newNetConnection.NeedsCustomization = $netConnection.NeedsCustomization
$newNetConnection.NetworkConnectionIndex = $netConnection.NetworkConnectionIndex
$newNetConnection.IpAddress = $ipAddress
$newNetConnection.IsConnected = $netConnection.IsConnected
#$newNetConnection.MACAddress = $netConnection.MACAddress
$newNetConnection.IpAddressAllocationMode = "MANUAL"
[VMware.VimAutomation.Cloud.Views.NetworkConnectionSection] $newNetConnectionSection = New-Object VMware.VimAutomation.Cloud.Views.NetworkConnectionSection
$newNetConnectionSection.NetworkConnection = ,$newNetConnection
$newNetConnectionSection.Info = $netConnectionSection.Info
# Define the mapping between the template VM's network and the vApp network in the target vApp
$instantiationSection = New-Object VMware.VimAutomation.Cloud.Views.NetworkAssignment
$instantiationSection.InnerNetwork = $netConnection.Name
$instantiationSection.ContainerNetwork = $netConfig.Name
# Define the guest OS settings of the newly created VM by configuring the new Computer Name (hostname).
$templateGuestSection = $vmTemplateView.Section | where { $_ -is [VMware.VimAutomation.Cloud.Views.GuestCustomizationSection] }
[VMware.VimAutomation.Cloud.Views.GuestCustomizationSection] $guestSection = `
New-Object VMware.VimAutomation.Cloud.Views.GuestCustomizationSection
$guestSection.Enabled = $templateGuestSection.Enabled
$guestSection.ComputerName = $compName
$guestSection.Info = $templateGuestSection.Info
# Define the recomposition specification
[VMware.VimAutomation.Cloud.Views.SourcedCompositionItemParam] $importedVmItem = `
New-Object VMware.VimAutomation.Cloud.Views.SourcedCompositionItemParam
$importedVmItem.Source = New-Object VMware.VimAutomation.Cloud.Views.Reference
$importedVmItem.Source.Href = $vmTemplateView.Href # Specify the template VM to be used
$importedVmItem.Source.Name = $newVMName # Specify the name of the newly create VM
$importedVmItem.InstantiationParams = New-Object VMware.VimAutomation.Cloud.Views.InstantiationParams
$importedVmItem.InstantiationParams.Section = $newNetConnectionSection, $guestSection # Define the IP and computer name of the new VM
$importedVmItem.NetworkAssignment = , $instantiationSection # Define the Network mapping of the new VM
[VMware.VimAutomation.Cloud.Views.SourcedCompositionItemParam[]] $sourcedItem = , $importedVmItem
Write-Host "Cloning VM '$templateVmName' into vApp '$vappName' under the name '$newVMName' with Computer Name '$compName' attaching its only NIC to network '$orgNetName' with the IP '$ipAddress'"
$vappView.RecomposeVApp($null, $null , $null, $null, $sourcedItem, $null, $null, $null, $null, $vappView.Name, $vappView.Description)
$newVM = Get-CIVApp -Id $vappView.Id | Get-CIVM -Name $newVmName
if($powerOn)
{
$newVM.ExtensionData.PowerOn()
}
return Get-CIVApp -Id $vappView.Id | Get-CIVM -Name $newVmName
Some remarks on your script and the error:
You are trying to assign references to CreateItem. CreateItem is used when you want to create a VM from scratch in the vApp. To use a template VM, set the SourcedItem property instead of CreateItem and set its source to the references that you try to currently assign to CreateItem.
Thanks Atanas, with some slight modifications I was able to get your script working as expected! I guess I was way off the mark Great work!
-Dean
I am getting the below error on running the RecomposeVApp command :
Exception calling "RecomposeVApp" with "11" argument(s): "The operation failed because no suitable resource was found.
Hub "Resources" doesn't have access to network "ONET_ADMIN_nPROD"."
At line:16 char:5
+ $vappView.RecomposeVApp($null, $null , $null, $null, $sourcedItem, $null, $n ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : CloudException
Could you suggest which access is missing here ? !