I am trying to write a script that would create a scheduled task for a cross-site vMotion. I can create that scheduled task through the GUI and it works. The environment is 3 linked 7.0 sites. From P...
See more...
I am trying to write a script that would create a scheduled task for a cross-site vMotion. I can create that scheduled task through the GUI and it works. The environment is 3 linked 7.0 sites. From PowerShell there are connected VISessions to all three VC servers. When trying to do it through the script below, If I make sure sure that $scheduledTaskManager instance is from the VC where the VM is currently located then it throws errors for objects that are on the destination site. Errors like: Exception calling "CreateScheduledTask" with "2" argument(s): "The object 'vim.ResourcePool:resgroup-1002' has already been deleted or has not been completely created" At C:\Scripts\MigrateTo-IMDC\Create-VMMoveScheduledTask.ps1:123 char:12 + return ($scheduledTaskManager.CreateScheduledTask($vmView.MoRef, ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : VimException If I remove the resource pool then it complains about the datastore: Exception calling "CreateScheduledTask" with "2" argument(s): "The object 'vim.Datastore:datastore-1411' has already been deleted or has not been completely created" At C:\Scripts\MigrateTo-IMDC\Create-VMMoveScheduledTask.ps1:123 char:5 + $scheduledTaskManager.CreateScheduledTask($vmView.MoRef, $spec) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : VimException If I remove the datastore then it complains about the destination Host. And so on. If I let $scheduledTaskManager enumerate ScheduledTaskManagers from all 3 sites then it cant find the VM: Exception calling "CreateScheduledTask" with "2" argument(s): "The object 'vim.VirtualMachine:vm-107863' has already been deleted or has not been completely created" At C:\Scripts\MigrateTo-IMDC\Create-VMMoveScheduledTask.ps1:123 char:12 + return ($scheduledTaskManager.CreateScheduledTask($vmView.MoRef, ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : VimException My script is as follows. Any help would be much appreciated. function Create-VMMoveScheduledTask { Param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, [Alias("Folder")] [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [VMware.VimAutomation.ViCore.Types.V1.Inventory.Folder] $DestinationFolder, [Alias("VMHost")] [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost] $DestinationHost, [Alias("Datastore")] [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [VMware.VimAutomation.ViCore.Types.V1.DatastoreManagement.Datastore] $DestinationDatastore, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] # Array of Hashes. Keys = MACAddress. Values = PortGroup (object). [ValidateScript({ if ($_.keys | Where-Object {$_ -notmatch "^[a-fA-F0-9]{2}([:-]?[a-fA-F0-9]{2}){5}$"}) {return $false} if ($_.values | Where-Object {!($_ -is [VMware.VimAutomation.Vds.Types.V1.VDPortgroup])}) {return $false} return $true; })] $vNICPortGroups, [Alias("Name")] [Parameter(Mandatory = $true)] [String] $TaskName = "Create-VMMoveScheduledTask $(Get-Date -Format G)", [Alias("Description")] [Parameter(Mandatory = $true)] [String] $TaskDescription = "Create-VMMoveScheduledTask $(Get-Date -Format G)", [Parameter(Mandatory = $true)] [ValidateScript({([DateTime]$_) -gt (([DateTime]::Now).AddSeconds(15)) -and ([DateTime]$_) -lt (([DateTime]::Now).AddDays(7))})] [DateTime] $StartTime, [Alias("Email")] [Parameter()] [ValidatePattern("^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")] [string] $AlertEmail ) #$si = Get-View ServiceInstance -Server ($VM.Uid -replace "^.*@(.*):.*$",'$1') $si = Get-View ServiceInstance #$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager -Server ($VM.Uid -replace "^.*@(.*):.*$",'$1') $scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager $vmView = $VM | Get-View # ScheduledTask specs $spec = New-Object VMware.Vim.ScheduledTaskSpec $spec.Name = $TaskName $spec.Description = $TaskDescription $spec.Enabled = $true if ($AlertEmail) {$spec.Notification = $AlertEmail} $spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler $spec.Scheduler.runat = $StartTime $spec.Action = New-Object VMware.Vim.MethodAction $spec.Action.Name = "RelocateVM_Task" # vMotion specs $arg1 = New-Object VMware.Vim.MethodActionArgument $arg1.Value = New-Object VMware.Vim.VirtualMachineRelocateSpec # ServiceLocator for destination - we should not need this #$arg1.Value.service = New-Object VMware.Vim.ServiceLocator #$arg1.Value.service.instanceUuid = ($global:defaultviservers | Where-Object {$DestinationHost.Uid -match $_.Name}).InstanceUuid.toUpper() # Destination Datastore $arg1.Value.datastore = $DestinationDatastore.Id # Destination Host $arg1.Value.host = $DestinationHost.Id # Destination ResourcePool if ($DestinationHost.ParentId -match "Cluster") { $arg1.Value.pool = ($DestinationHost | Get-Cluster).ExtensionData.ResourcePool } else { $arg1.Value.pool = $DestinationHost.ExtensionData.ResourcePool } # # Destination Folder $arg1.Value.folder = ($DestinationFolder | Get-View).MoRef # vNIC PortGroups $arg1.Value.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec $VMNICs = $VM | Get-NetworkAdapter $VMNICs | ForEach-Object {$i = 0} { $arg1.Value.deviceChange[$i] = New-Object VMware.Vim.VirtualDeviceConfigSpec $arg1.Value.deviceChange[$i].Operation = "edit" $arg1.Value.deviceChange[$i].device = $_.ExtensionData $arg1.Value.deviceChange[$i].device.backing = New-Object VMware.Vim.VirtualEthernetCardDistributedVirtualPortBackingInfo $arg1.Value.deviceChange[$i].device.backing.port = New-Object VMware.Vim.DistributedVirtualSwitchPortConnection $arg1.Value.deviceChange[$i].device.backing.port.SwitchUuid = ($vNICPortGroups.($_.MacAddress) | Get-VDSwitch | Get-View).Uuid $arg1.Value.deviceChange[$i].device.backing.port.PortgroupKey = $vNICPortGroups.($_.MacAddress).Key $i++ } $spec.Action.Argument += $arg1 # Set vMotion priority $arg2 = New-Object VMware.Vim.MethodActionArgument $arg2.Value = [VMware.Vim.VirtualMachineMovePriority]"defaultPriority" $spec.Action.Argument += $arg2 # Create scheduledTask return ($scheduledTaskManager.CreateScheduledTask($vmView.MoRef, $spec)) } thx.