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