Convert VMWare Machines in bulk to OVF using Windows PowerShell

I am always changing my tools up to whatever at that time feels good to use. After the recent updates to Virtualbox I decided that I would like to use it again however the issue that I had at the time was that I had so many virtual machines that it was a pain for me to convert them to OVF using the standard interface.

So I downloaded and installed the VMWare OVF Tool and dumped it in a simple source and destination bulk folder to folder conversion script. For me this converted like 95% of my virtual machines without any issues however some needed to be tweaked to remove the mounted ISO on a virtual machine.

Anyway when dumping in my VMWare virtual machine folder root it searches for all the machines it can convert and dumps them in the OVF Tool to convert to the destination folder. All in all I found it very easy to migrate over and am very happy with Virtualbox now.

If you find yourself in the same situation as me then maybe the code below that I wrote that helped me could help you. Keep in mind that I am still learning to code in PowerShell and I use it to help me in my every day tasks. Critique is always welcome 🙂

[cmdletBinding()]
Param
(
    [Parameter(Mandatory=$true)][String]$Source = "C:\Users\" + $env:UserName + "\Documents\",
    [Parameter(Mandatory=$true)][String]$Destination = "C:\Users\" + $env:UserName + "\Documents\",
    [String]$VMWareOVFTool = 'C:\Program Files\VMware\VMware OVF Tool\ovftool.exe',
    [Switch]$Overwrite
)

if (-Not(Test-Path $VMWareOVFTool))
{
    Write-Error 'VMWare OVF Tool is not found to be installed. You can specify a different location other than the default using the $VMWareOVFTool parameter'
    Exit
}

if (Test-Path -Path $Source -PathType Container)
{
    $VMWareMachines = Get-ChildItem $Source -Recurse -Filter "*.vmx"
}
elseif (((Get-ChildItem $Source).Extension) -eq '.vmx')
{
    $VMWareMachines = Get-ChildItem $Source
}

if (-Not($VMWareMachines))
{
    Write-Error "No VMWare Machine(s) could be found."
    Exit
}

foreach($Machine in $VMWareMachines)
{
    $MachineDestination = Join-Path $Destination -ChildPath (($Machine).BaseName + ".ovf")
   
    $count = 1

    Write-Verbose ("Testing destination file name for " + ($Machine).BaseName)
    if (-Not($Overwrite))
    {
        while(Test-Path $MachineDestination)
        {
            $MachineDestination = Join-Path $Destination -ChildPath (($Machine).BaseName + "-" + $count + ".ovf")
            $count = $count + 1
        }
    }

    Write-Verbose "Building up command line arguments for the OVF Tool"
    $ArgumentList = '"' + ($Machine).FullName + '" "' + $MachineDestination + '"'

    if ($Overwrite)
    {
        $ArgumentList = '-o ' + $ArgumentList
    }

    Write-Verbose ("Starting convert of " + ($Machine).BaseName)

    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = $VMWareOVFTool
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = $ArgumentList
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $p.WaitForExit()
    $stdout = $p.StandardOutput.ReadToEnd()
    $stderr = $p.StandardError.ReadToEnd()
    
    Write-Output $stdout

    Write-Verbose (($Machine).BaseName + " has been converted")
}

Leave a Comment