vCloud PowerCLI ExtensionData UpdateServerData Limit

Part of my cleanup from the vCloud Suite 5.1 upgrade is migrating everything off of the *Any storage profile. A piece of this is setting the DefaultStorageProfile property for templates, which by default is blank (meaning the *Any profile). I’ve written a function that I’m using to update these in mass:

function set-templateVmDefaultSP($templates,$sPName)
{
    foreach ($template in $templates){
        write-host "Changeing defaultStoragePofile for VMs in $template"
        $vms = $template.extensiondata.children.vm
        foreach ($vm in $vms){
            $vm.defaultstorageprofile = "$sPName"
        }
        $template.extensiondata.updateserverdata()
    }
}

This passes a list of templates and a storage profile name, iterates through the template’s VMs, changes/sets the DefaultStorageProfile and sends an XML update back to vCloud with the changes.

This was working all well and good until I ran into this error:

PowerCLI C:\scripts\vcloud> $template.extensiondata.updateserverdata()
Exception calling “UpdateServerData” with “0” argument(s): “The provided XML has too many elements: 3340. The maximum is 2,048.”
At line:1 char:41
+ $template.extensiondata.updateserverdata <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

Upon inspection of this template, it has 54 VMs. The problem was where I was calling the updateserverdata() method to send the changes up stream. This method sends a refresh of all sub-extensiondata. This means that I was sending updates for:
extensiondata.AnyAttr.*
extensiondata.Children.*
extensiondata.Client.*
extensiondata.DateCreated.*
extensiondata.DefaultStorageProfile.*
extensiondata.Description.*
extensiondata.Files.*
extensiondata.GoldMaster.*
extensiondata.Href.*
extensiondata.Id.*
extensiondata.Link.*
extensiondata.Name.*
extensiondata.OperationKey.*
extensiondata.OvfDescriptorUploaded.*
extensiondata.Owner.*
extensiondata.Section.*
extensiondata.Status.*
extensiondata.Tasks.*
extensiondata.Type.*
extensiondata.VAppScopedLocalId.*
extensiondata.VCloudExtension.*

This apparently adds up to 3340 updates. And also apparently, there’s a 2048 XML element limit for a single update. I’m sure this is in the API documentation somewhere, but I couldn’t find it.

The solution was to move the UpdateServerData method call into the VM section (.extensiondata.children.vm) so it only sends the update back to vcloud the XML updates for that VM, rather than the entire template. So the function now looks like:

function set-templateVmDefaultSP($templates,$sPName)
{
    foreach ($template in $templates){
        write-host "Changeing defaultStoragePofile for VMs in $template"
        $vms = $template.extensiondata.children.vm
        foreach ($vm in $vms){
            $vm.defaultstorageprofile = "$sPName"
            $vm.updateserverdata()
        }
    }
}