Created
June 4, 2018 18:07
-
-
Save BrandonStiff/c4193f4aeb73bec0746087590078eede to your computer and use it in GitHub Desktop.
Copy all VM vApp properties from one vCenter server to another.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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