Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Copy all VM vApp properties from one vCenter server to another.
function Copy-VmVAppProperty()
{
<#
.SYNOPSIS
This function copes all VM vApp properties from the VMs in one VCenter server to another.
.PARAMETER SourceVCenter
Specifies the source vCenter server.
.PARAMETER DestinationVCenter
Specifies the destination vCenter server.
.PARAMETER VM
If specified, then only the specified VMs are affected. The default is all VMs with vApp properties are affected.
.EXAMPLE
Copy-VmVAppProperty -SourceVCenter oldvcenter.domain.com -DestinationVCenter newvcenter.domain.com
#>
[CmdletBinding(SupportsShouldProcess)]
param
(
[Parameter(Mandatory)]
[string] $SourceVCenter,
[Parameter(Mandatory)]
[string] $DestinationVCenter,
[string[]] $Vm
)
function Set-VAppProperties()
{
[CmdletBinding(SupportsShouldProcess)]
param
(
[Parameter(Mandatory)]
[PSObject] $SourceVm,
[Parameter(Mandatory)]
[PSObject] $DestinationVm,
[Parameter(Mandatory)]
[PSObject] $DestinationViServer
)
$sourceProps = $SourceVm.ExtensionData.Config.VAppConfig.Property
$dstProps = $DestinationVm.ExtensionData.Config.VAppConfig.Property
$propsToUpdate = @()
foreach ( $prop in $sourceProps )
{
$dstProp = $dstProps | Where-Object { $_.Label -ieq $prop.Label }
if ( $dstProp )
{
# Update the property:
if ( Compare-Object -ReferenceObject $prop -DifferenceObject $dstProp -Property Key,Id,Label,Type,DefaultValue,Value,Description )
{
Write-Verbose ("Property $($prop.Label) is different on the destination. Updating...")
$propsToUpdate += New-Object -TypeName PSCustomObject -Property `
@{
"Type" = "edit"
"Property" = $prop
}
}
else
{
Write-Verbose ("Property $($prop.Label) is the same on the destination.")
}
}
else
{
# Add a new property:
Write-Verbose ("Property $($prop.Label) is not present on the destination. Adding...")
$propsToUpdate += New-Object -TypeName PSCustomObject -Property `
@{
"Type" = "add"
"Property" = $prop
}
}
}
if ( $propsToUpdate )
{
$vmSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vmSpec.vAppConfig = New-Object VMware.Vim.VmConfigSpec
$vmspec.vAppConfig.property = New-Object VMware.Vim.VAppPropertySpec[] ($propsToUpdate.Count)
foreach ( $prop in $propsToUpdate )
{
$new = New-Object VMware.Vim.VAppPropertySpec
$new.operation = $prop.Type
$new.Info = $prop.Property
$vmSpec.vAppConfig.Property += $new
}
if ( $PSCmdlet.ShouldProcess($DestinationVm.Name, "Update VM with new custom properties") )
{
Write-Host ("Configuring VM $($DestinationVm.Name) with new properties... ") -NoNewline
$taskId = $DestinationVm.ExtensionData.ReconfigVM_Task($vmSpec)
$start = Get-Date
while ( (Get-Task -Server $DestinationViServer | Where-Object { $_.Id -ieq $taskId.ToString() -and $_.State -ine "Success" }) -and (New-TimeSpan -Start $start) -le "00:05:00" )
{
Start-Sleep -Seconds 5
Write-Verbose ("Waiting for task to finish...")
}
$task = Get-Task -Server $DestinationViServer | Where-Object { $_.Id -ieq $taskId.ToString() }
Write-Verbose ("Reconfiguration task submitted.")
Write-Verbose ($task | Format-List | Out-String)
if ( $task -and $task.State -ieq "Success" )
{
Write-Host ("Successful.") -ForegroundColor Green
}
else
{
Write-Host ("Failed - $($task.Result)") -ForegroundColor Red
}
}
$DestinationVm = Get-Vm -Server $DestinationViServer -Name $DestinationVm.Name
}
else
{
Write-Host ("There are no properties to update on VM $($DestinationVm.Name).")
}
}
Import-Module Vmware.VimAutomation.Core -ErrorAction Stop
$srcCon = Connect-ViServer $SourceVCenter
$dstCon = Connect-viServer $DestinationVCenter
$srcVms = Get-VM -Server $srcCon | Where-Object { $_.ExtensionData.Config.VAppConfig.Property }
$dstVms = Get-VM -Server $dstCon
foreach ( $sv in $srcVms | Where-Object { !$Vm -or $Vm -icontains $_.Name } )
{
$dst = $dstVms | Where-Object { $_.Name -ieq $sv.Name }
if ( $dst )
{
Set-VAppProperties -SourceVm $sv -DestinationVm $dst -DestinationViServer $dstCon | Out-Null
}
else
{
Write-Warning ("Unable to find VM $($sv.Name) on the destination vCenter $($dstCon.Name)!")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment