image

Storage vMotion is a great feature to Move your VMs to other datastores. But what if you want to move your Templates?
In the current version of vSphere there is no option within the Client:

image

So I created a PowerCLI function just to migrate the templates to another datastore.

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

    if($template -eq ""){Write-Host "Enter a Template name"}
    if($esx -eq ""){Write-Host "Enter an ESX hostname"}
    if($esx -ne "" -and $datastore -eq ""){$vmotion = $true}
    if($datastore -ne ""){$svmotion = $true}

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

    if($svmotion){
        Write-Host "Migrate $template to $esx and $datastore"
        Move-VM -VM (Get-VM $vm) -Destination (Get-VMHost $esx) `
        -Datastore (Get-Datastore $datastore) -Confirm:$false
        (Get-VM $vm | Get-View).MarkAsTemplate() | Out-Null
    }        

    if($vmotion){
        Write-Host "Migrate $template to $esx"
        Move-VM -VM $vm -Destination (Get-VMHost $esx) -Confirm:$false
        ($vm | Get-View).MarkAsTemplate() | Out-Null
    }
}

The function above can be used to move a single template via

Move-Template <template> <esxhost> <datastore>

But what if you want to move only your Linux Templates or Windows Templates or even all the Templates at once.  For these options, I created two extra functions.

First I created a function to get al the Linux templates:

function Get-LinuxTemplates{
    $lnxtpl = Get-Template | Get-View | `
    where {$_.Guest.GuestFamily -eq 'linuxGuest'} | `
    Get-VIObjectByVIView
    return $lnxtpl
}

image

And if you want, you can also get al the Windows templates:

function Get-WindowsTemplates{
    $wintpl = Get-Template | Get-View | `
    where {$_.Guest.GuestFamily -eq 'windowsGuest'} | `
    Get-VIObjectByVIView
    return $wintpl
}

image

Now we can get all the different templates, we are able to move the templates to another host or datastore.

This is how you move all the templates to a new host and datastore:

$templates = Get-Template
foreach($tpl in $templates){
    Move-Template $tpl <esxhost> <datastore>
}

image

If you want to move all the Linux templates, you run the following commands:

$templates = Get-LinuxTemplates
foreach($tpl in $templates){
    Move-Template $tpl <esxhost> <datastore>
}

And finally, you can move all windows templates by running these commands:

$templates = Get-WindowsTemplates
foreach($tpl in $templates){
    Move-Template $tpl <esxhost> <datastore>
}

But how does it look when you run the function. I will do an example with the get-linuxtemplates function.

image

I am going to use this functions in another script and will transform it to a ready to use script for the EcoShell.

15 thoughts on “PowerCLI: Move-Template

  1. Hello

    I just convert my templates to a virtual machine, then I move the templates to the other datastore and convert it back to templates.

    Regards

    1. Of course you do – that is the obvious and high-maintenance way of doing that. If you have 50 templates, are you going to spend a week or two doing it?

  2. really sweet stuff, thanks! wish vmware would develop the template concept a bit further, it’s quite annoying to have to manually reregister templates to a specific host for reinstalls, if they need to be registered on a host then vmotion should take care of them too.

  3. Great script just what I needed as I have about 30-40 templates to move and don’t feel like converting to VM and moving wash rinse and repeat.

  4. I got the following error, would you kindly help me out?

    [vSphere PowerCLI] C:\tools > .\Move-Template Win2003_SP2 192.168.0.1 LUN6
    (no error but the template did not move)

    [vSphere PowerCLI] C:\tools > Move-Template Win2003_SP2 192.168.0.1 LUN6
    Move-Template : A parameter cannot be found that matches parameter name “LUN6”
    at line:1 char:14
    + Move-Template <<< .\Get-LinuxTemplates

    '<' operator is reserved for future use
    at C:\tools\Get-LinuxTemplates.ps1:3 char:25
    + Move-Template $tpl < <<<
    + CategoryInfo : ParserError: (<:OperatorToken) [], ParseException
    + FullyQualifiedErrorId : RedirectionNotSupported

  5. ——=== SORRY, the following should be the correct output ===——

    [vSphere PowerCLI] C:\tools > .\Move-Template Win2003_SP2 192.168.0.1 LUN6
    (no error but the template did not move)

    [vSphere PowerCLI] C:\tools > Move-Template Win2003_SP2 192.168.0.1 LUN6
    Move-Template : A parameter cannot be found that matches parameter name “LUN6”
    at line:1 char:14
    + Move-Template <<< .\Get-LinuxTemplates

    '<' operator is reserved for future use
    at C:\tools\Get-LinuxTemplates.ps1:3 char:25
    + Move-Template $tpl < <<<
    + CategoryInfo : ParserError: (<:OperatorToken) [], ParseException
    + FullyQualifiedErrorId : RedirectionNotSupported

  6. I am trying to run this script to move templates to a datastore in a different datacenter and I get this error. Can it only copy templates to the local datacenter in vcenter?
    Move-VM : 2/22/2016 10:49:08 AM Move-VM Destination container must
    be in the same Datacenter.
    At C:\source\scripts\vmware\Working\MoveTemplates.ps1:14 char:9
    + Move-VM -VM (Get-VM $vm) -Destination (Get-VMHost $esx) `
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (sfesx1.kkr.com:VMHostImpl) [Mo
    ve-VM], VimException
    + FullyQualifiedErrorId : Client20_VmHostServiceImpl_CheckMoveVmParameters
    _InvalidDatacenter,VMware.VimAutomation.ViCore.Cmdlets.Commands.MoveVM

    1. Unfortunately you are only able to move objects inside a datacenter object. So you can use the move-vm cmdlet for object inside the datacenter, but not to move objects between datacenter objects. So you’re right 🙂

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.