Hi All,
Is it possible to export vApp using PowerCLI?
We have DR requirement which stats - All vApp created in DC-A should be available in DC-B.
As long as place holder vApp's are available we always import VMs from vCenter.
Thanks,
Preetam
One feature I find particularly useful is the "Lossless" export for vApp templates. This preserves the personality of all of the VMs (UUIDs, MAC addresses, etc.). It is less portable than a "regular" export, but saves time if you're going between vCD instances.
I took Clint Kitson's Export-CiOVF and modified it a little to leverage this new feature:
Function Export-CIOvfLossless {
<#
.DESCRIPTION
Export VAppTemplate while maintaining identity
.EXAMPLE
PS C:\> Get-CIVAppTemplate myVappTempalte | Export-CIOvfLossless
#>
PARAM(
$targetDir,
[Parameter(Mandatory=$True, Position=1, ValueFromPipeline=$true)]
[PSObject[]]$InputObject
)
PROCESS {
$InputObject | %{
if(!($_ | Get-CIView | %{ $_.Link } | where {$_.Rel -eq "download:identity"})) {
try {
Write-Host "Enabling download..."
$_ | Get-CIView | %{ $_.EnableDownload() }
} catch {
Write-Error $error[0]
}
}
$href = $_ | Get-CIView | %{ $_.Link } | where {$_.Rel -eq "download:identity"} | %{ $_.Href }
if(!$targetDir) { $targetDir = $_.name }
if($href) {
$serverName = ($href.Split("/"))[2]
$cloudServer = $global:DefaultCIServers | where {$_.Name -eq $serverName }
$sessionId = $cloudServer.sessionid
$webClient = New-Object system.net.webclient
$webClient.Headers.Add('x-vcloud-authorization',$sessionId)
if(!(Test-Path $targetDir)) { New-Item -type Directory $targetDir | out-null }
$targetDir = (Get-Item $targetDir).FullName
$baseHref = $href -replace "descriptor-with-id.ovf",""
$webClient.DownloadFile("$href","$($targetDir)\descriptor-with-id.ovf")
[xml]$xmlDescriptor = Get-Content "$($targetDir)\descriptor-with-id.ovf"
$xmlDescriptor.Envelope.References.File | %{ $_.href } | %{
try {
Write-Host "Downloading $($targetDir)\$($_)"
$webClient.DownloadFile("$($baseHref+$_)","$($targetDir)\$($_)")
} catch {
Write-Host -fore red "Error downloading OVF disk named $($_)"
}
}
} else {
Write-Host -fore red "OVF Download Link Not Found"
}
Write-Host "Disabling download"
$_ | Get-CIView | %{ $_.DisableDownload() }
}
}
} #Export-CIOvfLossless
Absolutely. I do this all the time.
Look at the stuff from Clinton Kitson for the export
http://velemental.com/2012/06/05/importing-and-exporting-vapptemplates-from-ovfs-with-powercli/
I use the Import-CIVappTemplate command to do the imports, although it can be a little buggy for large vapps -- the next release is supposed to contain some optimizations.
-Doug
One feature I find particularly useful is the "Lossless" export for vApp templates. This preserves the personality of all of the VMs (UUIDs, MAC addresses, etc.). It is less portable than a "regular" export, but saves time if you're going between vCD instances.
I took Clint Kitson's Export-CiOVF and modified it a little to leverage this new feature:
Function Export-CIOvfLossless {
<#
.DESCRIPTION
Export VAppTemplate while maintaining identity
.EXAMPLE
PS C:\> Get-CIVAppTemplate myVappTempalte | Export-CIOvfLossless
#>
PARAM(
$targetDir,
[Parameter(Mandatory=$True, Position=1, ValueFromPipeline=$true)]
[PSObject[]]$InputObject
)
PROCESS {
$InputObject | %{
if(!($_ | Get-CIView | %{ $_.Link } | where {$_.Rel -eq "download:identity"})) {
try {
Write-Host "Enabling download..."
$_ | Get-CIView | %{ $_.EnableDownload() }
} catch {
Write-Error $error[0]
}
}
$href = $_ | Get-CIView | %{ $_.Link } | where {$_.Rel -eq "download:identity"} | %{ $_.Href }
if(!$targetDir) { $targetDir = $_.name }
if($href) {
$serverName = ($href.Split("/"))[2]
$cloudServer = $global:DefaultCIServers | where {$_.Name -eq $serverName }
$sessionId = $cloudServer.sessionid
$webClient = New-Object system.net.webclient
$webClient.Headers.Add('x-vcloud-authorization',$sessionId)
if(!(Test-Path $targetDir)) { New-Item -type Directory $targetDir | out-null }
$targetDir = (Get-Item $targetDir).FullName
$baseHref = $href -replace "descriptor-with-id.ovf",""
$webClient.DownloadFile("$href","$($targetDir)\descriptor-with-id.ovf")
[xml]$xmlDescriptor = Get-Content "$($targetDir)\descriptor-with-id.ovf"
$xmlDescriptor.Envelope.References.File | %{ $_.href } | %{
try {
Write-Host "Downloading $($targetDir)\$($_)"
$webClient.DownloadFile("$($baseHref+$_)","$($targetDir)\$($_)")
} catch {
Write-Host -fore red "Error downloading OVF disk named $($_)"
}
}
} else {
Write-Host -fore red "OVF Download Link Not Found"
}
Write-Host "Disabling download"
$_ | Get-CIView | %{ $_.DisableDownload() }
}
}
} #Export-CIOvfLossless
Hi Doug,
I think my question was not properly framed. However Thanks for the script and the link.
We have a drafted a solution where in we will backup VM using VDP and restore it back.
If VM is lost from vCenter, we will restore VM but this gets restore as VM not as vApp.
Therefore we choose to import VM into vCloud director.
Here is where my question was about importing and exporting vApp really came in my mind.
With your solution I would need lot of disk space and not true back solution I can put in place.
again thanks
I agree, it requires a *LOT* of disk space. The way I do things, I export the vApp to disk (an NTFS-formatted drive on my "vApp library" server), replicate that to my DR site, then import the vApp templates from the remote "vApp library" server into the remote vCD instance. Ultimately, I need enough space for a little less than 4 copies of my vApps, but I have multiple recovery options as well, and I can have the whole vApp ready to go (as of a point in time) in the remote cloud.
I like your solution as well, but it doesn't quite fit my use case. All of the exporting/importing does consume a lot of time, so you are likely able to achieve much lower RPOs than I am, but I can possibly have a quicker RTO since my whole vApp is ready to go... but its data would be more stale than yours. Again, it all comes down to use case.
Cheers,
Doug