Changing VM storage policies in vCloud Director 5.5 with PowerCLI

Posted by

I was recently asked to create a PowerCLI script for changing VM storage policies in a vCloud Director 5.5 environment.  It seems like vCloud Director 5.x doesn’t have the tightest integration with storage policies so it’s not as simple as running something like ‘Set-VM’ and passing a new storage policy.  The script searches for all VMs on a source storage policy and migrates them to the destination storage policy.   As always, test in your environment.

$vCDServer = 'vcd55.vmware.local'
$sourceStorageProfile = 'SiteA'
$destinationStorageProfile = 'SiteB'

# See https://communities.vmware.com/message/2372019. If you don't set the compatibility to 5.1, you'll receive the error:
# Exception calling "UpdateServerData" with "0" argument(s): "Bad request  - Unexpected JAXB Exception  - cvc-complex-type.2.4.a: Invalid content was found starting with element 'AdminAutoLogonEnabled'. One of '{"http://www.vmware.com/vcloud/v1.5":Link, WC[##other:"http://www.vmware.com/vcloud/v1.5"]}' is expected."
#    At line:10 char:1
#    + $GuestCustomization.UpdateServerData()
#    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
#    + FullyQualifiedErrorId : CloudException

[VMware.VimAutomation.Cloud.Views.CloudClient]::ApiVersionRestriction.ForceCompatibility("5.1")

connect-ciserver $vCDServer

# Get all VMs on the source policy
$vms = get-civm | ? { $_.ExtensionData.StorageProfile.Name -eq $sourceStorageProfile }

if ($vms) { # If we found any VMs. 
  $vms | % {
    $vm = $_  # Set the loop variable to something more readable
    write-host "Processing VM '$($vm)'"
    $newStorageProfile = $vm.orgvdc.ExtensionData.VdcStorageProfiles.VdcStorageProfile | ? { $_.name -eq $destinationStorageProfile }
    if ($newStorageProfile) {
      write-host "Found storage profile '$($newStorageProfile.name)' in org vDC '$($vm.orgvdc)'"
      write-host "Moving VM '$($vm.name)' to storage profile '$($destinationStorageProfile)'"
      $vm.ExtensionData.StorageProfile = $newStorageProfile
      try {
        $vm.ExtensionData.UpdateServerData()
      }
      Catch {
        write-host "Unable to update VM: " -NoNewLine -foregroundcolor "yellow"
        write-host "$($_.Exception.Message)" -foregroundcolor "red"
      }
      $newStorageProfile = $null
    }
    else {
      write-host "Unable to find storage profile '$($destinationStorageProfile)' in org vDC '$($vm.orgvdc)'"
    }
    write-host '-------------'
  }
}
else {
  write-host "No VMs found on storage profile '$($sourceStorageProfile)'"
}

One comment

  1. This is just the section to change default policies (not to create one)

    cls
    $orgvDCName = “OrgVDC_Name” # OrgVDC
    $storageProfile = “Datastore001” # Storage Profile to make default

    $orgvDCStorageProfile = search-cloud -querytype AdminOrgVdcStorageProfile | where {($_.Name -match $storageProfile) -and ($_.VdcName -eq $orgvDCName)} | Get-CIView

    #Set the new storage profile as default
    $orgvDCStorageProfile.Default = $True
    $orgvDCStorageProfile.UpdateServerData() | out-null

Leave a comment