Issue Building PowerCLI Mass OVF Export Tool

2.2k views Asked by At

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:

  • Through PowerCLI arguments, take in the vCenter address, naming scheme of the VMs to export, and where the OVFs should be exported
  • Connect to the vCenter instance
  • Put all VMs that follow the specified naming scheme into a list
  • Loop through the list and export each VM to an ovf using the ovftool and the built path to the VM

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:

  • The output of "get-vm -name vm_name | .\get-vmfolderpath.ps1" run directly in the PowerCLI console returns the proper VM path
  • All variables output the expected values
  • If the exact ovftool command generated in the script is run in the PowerCLI console then it will properly export the VM
1

There are 1 answers

0
Chris Willis On BEST ANSWER

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