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)'"
}
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