powershellvmwarepowercliovf

Issue Building PowerCLI Mass OVF Export Tool


Background

I am creating a script, using PowerCLI, to perform mass OVF exports using VMware's ovftool. The script works by performing the following functions:

The Script: VMs-to-OVF.ps1

# Take in vCenter address, naming scheme of VMs to be exported, and where the OVFs should be exported

param (

[string]$vcenter = $(throw "

    vCenter address required.`n

    Example:`n

    .\VMs-to-OVF.ps1 -vcenter <192.168.1.200>`n

    .\VMs-to-OVF.ps1 -vcenter <vcenter.test.com>"),

[string]$vmNamingScheme = $(throw "

    VM naming scheme required.`n

    Example:`n

    .\VMs-to-OVF.ps1 -vcenter <vcenterIP/DNS> -vmPath </DATACENTER/vm/`n

    test/> -vmNamingScheme <test-vm-1>`n

    .\VMs-to-OVF.ps1 -vcenter <vcenterIP/DNS> -vmPath </DATACENTER/vm/`n

    test/> -vmNamingScheme <test-vm-*>`n"),

[string]$exportLocation = $(throw "

    Export location required.`n

    Example:`n

    .\VMs-to-OVF.ps1 -vcenter <vcenterIP/DNS> -vmPath </DATACENTER/vm/`n

    test/> -vmNamingScheme <test-vm-1> -exportLocation 192.168.1.100:\`n

    .\VMs-to-OVF.ps1 -vcenter <vcenterIP/DNS> -vmPath </DATACENTER/vm/`n

    test/> -vmNamingScheme <test-vm-*> -exportLocation X:\`n")

)

# Connect to vCenter

Connect-VIServer -Server $vcenter

# $VMs is an array of VM names that will be exported
# $vmNamingScheme gives the VM naming pattern we are looking for

$VMs = $(get-vm -name $vmNamingScheme | select name | format-list | out-string)
$VMs = $VMs.replace("Name : ","")
$VMs = $VMs.replace(" ","")
$VMs = $VMs.split("`n")
$VMs = $VMs|?{$_ -ne $VMs[1]}

# This loop iterates through the $VMs array and performs an OVF export, to the location
# specified in $exportLocation, for each VM name in the array
# $vmPath is comprised of the path to the VM and $VM holds the actual VM name

foreach ($VM in $VMs){
    if ($VMs -ne $null){ 

    # ***THIS SCRIPT ASSUMES THE get-vmfolderpath SCRIPT IS IN THE SAME DIRECTORY AS ITSELF***
    # get the folder path of the VM using the get-vmfolderpath script (this will align with
    # the path in vSphere Folders and Templates view)

    $vmPath = "get-vm -name $VM | .\get-vmfolderpath.ps1"
    &$vmPath

    # ***THIS SCRIPT ASSUMES THE DEFAULT INSTALL PATH FOR THE ovftool PROGRAM
    # run the ovftool command with the proper arguments

    &'C:\Program Files\VMware\VMware OVF Tool\ovftool.exe' vi://$vcenter$vmPath$VM $exportLocation
    }
}

Accompanying Script: get-vmfolderpath

param(
    [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
    [string]$folderid,
    [switch]$moref
)

$folderparent=get-view $folderid

if ($folderparent.name -ne 'vm'){
    if($moref){
        $path=$folderparent.moref.toString()+'\'+$path
    }
    else{
        $path=$folderparent.name+'\'+$path
    }
    if ($folderparent.parent){
        if($moref){
            get-vmfolderpath $folderparent.parent.tostring() -moref
        }
        else{
            get-vmfolderpath($folderparent.parent.tostring())
        }
    }
}
else {
    if ($moref){
        return (get-view $folderparent.parent).moref.tostring()+"\"+$folderparent.moref.tostring()+"\"+$path
    }
    else {
        return (get-view $folderparent.parent).name.toString()+'\'+$folderparent.name.toString()+'\'+$path
    }
}

Errors

The ovftool command built in each iteration of the for loop will work if you copy and paste the text into the PowerCLI console, but not when run directly from the script. The following errors are produced when the custom ovftool command is run from within the script:

The term 'get-vm -name VM-NAME | .\get-vmfolderpath.ps1' is not
recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify
that the path is correct and try again.At
C:\Users\username\Desktop\VMs-to-OVF.ps1:85 char:4
+         &$vmPath
+          ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (get-vm -name CA...mfolderpath.p
   s1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Things I Have Checked:


Solution

  • Just closing the loop on this. I found a solution to my issue. My guess is that something is lost when you manipulate the list of VMs returned by the Get-VM cmdlet. In the VMs-to-OVFs script, if all of the "$VM =" lines are replaced by the single line below, then that information is retained.

    $VMs = get-vm -name $vmNamingScheme

    In the for loop use the ".Name" attribute to pass each individual VM object to the get-vmfolderpath script.

    $vmPath = get-vm -name $VM.Name | .\get-vmfolderpath.ps1