Tuesday, July 12, 2011

sVmotion VMware templates

I am doing some VMware datastore shuffling and needed to move several templates to another datastore. For normal VMs, I have a script named "Move-VMThin.ps1" that moves the VMs and thins out the disks at the same time. I looked for something similar for templates, something that would allow me to migrate the template to other storage, and there was no native support.

A little googling and I found http://ict-freak.nl/2010/01/21/powercli-move-template/. It appears that you have to convert the template to a VM, move the VM, and convert it back to a template. This is fine, but a pain if you have dozens of templates.

$vmName = $args[0]
$dsName = $args[1]


function Move-VMTemplate{
    param( [string] $template, [string] $datastore)

    if($template -eq ""){Write-Host "Enter a Template name"}
    if($datastore -ne ""){$svmotion = $true}

    Write-Host "Converting $template to VM"
    $vm = Set-Template -Template (Get-Template $template) -ToVM 

    Write-Host "Migrate $template to $datastore"
    # Move-VM -VM (Get-VM $vm) -Destination (Get-VMHost $esx) -Datastore (Get-Datastore $datastore) -Confirm:$false
    Move-VMThin (Get-VM $vm) (Get-Datastore $datastore)
    
    Write-Host "Converting $template to template"
    (Get-VM $vm | Get-View).MarkAsTemplate() | Out-Null
}

function Move-VMThin {
    PARAM(
         [Parameter(Mandatory=$true,ValueFromPipeline=$true,HelpMessage="Virtual Machine Objects to Migrate")]
         [ValidateNotNullOrEmpty()]
            [System.String]$VM
        ,[Parameter(Mandatory=$true,HelpMessage="Destination Datastore")]
         [ValidateNotNullOrEmpty()]
            [System.String]$Datastore
    )
    
 Begin {
        #Nothing Necessary to process
 } #Begin
    
    Process {        
        #Prepare Migration info, uses .NET API to specify a transformation to thin disk
        $vmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$VM"}
        $dsView = Get-View -ViewType Datastore -Filter @{"Name" = "$Datastore"}
        
        #Abort Migration if free space on destination datastore is less than 50GB
        if (($dsView.info.freespace / 1GB) -lt 50) {throw "Move-ThinVM ERROR: Destination Datastore $Datastore has less than 50GB of free space. This script requires at least 50GB of free space for safety. Please free up space or use the VMWare Client to perform this Migration"}

        #Prepare VM Relocation Specificatoin
        $spec = New-Object VMware.Vim.VirtualMachineRelocateSpec
        $spec.datastore =  $dsView.MoRef
        $spec.transform = "sparse"
        
        #Perform Migration
        $vmView.RelocateVM($spec, $null)
    } #Process
}


Move-VMTemplate $vmName $dsName

1 comment:

vCloud Guy said...

I am trying to run this script but getting this error when I run the command below

Move-VMTemplate
Converting Template to VM
Migrating Template to datastore


Exception calling "RelocateVM" with "2" argument(s): "The operation is not
allowed in the current state."
At C:\source\scripts\vmware\Working\MoveVMTemplatetoDS.ps1:49 char:9
+ $vmView.RelocateVM($spec, $null)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : VimException


Any ideas?