VMware Cloud Community
willisc
Contributor
Contributor

Issue Building PowerCLI Mass OVF Export Tool

I have also posted this question on StackOverflow here: powershell - Issue Building PowerCLI Mass OVF Export Tool - Stack Overflow

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:

  1. Through PowerCLI arguments, take in the vCenter address, naming scheme of the VMs to export, and where the OVFs should be exported
  2. Connect to the vCenter instance
  3. Put all VMs that follow the specified naming scheme into a list
  4. 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

# If this returns a CommandNotFoundException then you need to add the current

# directory location to your PATH variable using the command:

# $env:PATH=$env:PATH+";."

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
0 Kudos
0 Replies