VMware Cloud Community
meistermn
Expert
Expert
Jump to solution

relocate vm's from csv file and create schedule task in VC

What is wrong with the last line "$scheduledTaskManager.CreateScheduledTask($vmView.MoRef, $task) " ?

  1. The ScheduledTaskManager is in the Service Instance.

$si = get-view ServiceInstance

$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

  1. We need to identify the VM and the host where it will be powered on.

#$vmView = Get-VM PowerOnTest | Get-View

#$esxView = Get-VMHost esx35-01.vitoolkit.local | Get-View

foreach ($f in (import-csv `

"D:\MigrateStorage\amsterdam-core-hp-poweron.csv"))

{

$vmView=$f

*

echo $vmView

*

}

  1. Now we construct the task argument.

$arg = New-Object VMware.Vim.MethodActionArgument

#$arg.Value = $esxview.MoRef

$action = New-Object VMware.Vim.MethodAction

$action.Argument = $arg

$action.Name = "PowerOnVM_Task"

$scheduler = new-object VMware.Vim.OnceTaskScheduler

$scheduler.runat = (get-date).addminutes(5)

$task = New-Object VMware.Vim.ScheduledTaskSpec

$task.Action = $action

$task.Description = "Start a VM with a scheduled task."

$task.Enabled = $true

$task.Name = "Power On Virtual Machine"

$task.Scheduler = $scheduler

$scheduledTaskManager.CreateScheduledTask($vmView.MoRef, $task)

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The following script should do the trick.

$csvName = <CSV-file>
$tgtDatastore = <datastore-name>
$emailAddr = <email-address> 
$startTime = <start-datetime>	             # Ex [Datetime]"10/21/2009 20:00"
$startInterval = <minutes-between>

$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

$offset = 0
Import-Csv $csvName | % {
	$vm = Get-View -ViewType VirtualMachine -Filter @{"Name"=$_.VMname}

	$spec = New-Object VMware.Vim.ScheduledTaskSpec
	$spec.Name = "svMotion " + $_.VMname
	$spec.Description = "Migrate " + $_.VMname + " to " + $tgtDatastore
	$spec.Enabled = $true
	$spec.Notification = $emailAddr
	$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
	$spec.Scheduler.runat = $startTime.AddMinutes($offset)
	$offset += $startInterval
	$spec.Action = New-Object VMware.Vim.MethodAction
	$spec.Action.Name = "RelocateVM_Task"

	$arg1 = New-Object VMware.Vim.MethodActionArgument
	$arg1.Value = New-Object VMware.Vim.VirtualMachineRelocateSpec
	$arg1.Value.datastore = (Get-Datastore $tgtDatastore | Get-View).MoRef
 	$arg1.Value.pool = $vm.ResourcePool
 	$arg1.Value.host = $vm.Runtime.Host

	$spec.Action.Argument += $arg1
	$arg2 = New-Object VMware.Vim.MethodActionArgument
	$arg2.Value = [http://VMware.Vim.VirtualMachineMovePriority|http://VMware.Vim.VirtualMachineMovePriority]"defaultPriority"
	$spec.Action.Argument += $arg2
	
	$scheduledTaskManager.CreateScheduledTask($vm.MoRef, $spec) 
}

Allthough the scheduled task will trigger a svMotion, the CreateScheduledTask method still seems to require a host and resourepool MoRef in the VirtualMachineRelocateSpec argument.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
24 Replies
LucD
Leadership
Leadership
Jump to solution

You need to pass the MoRef of a VirtualMachine object as the first parameter to the CreateScheduledTask method.

You could do it this way

$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager
#$vmView = Get-VM PowerOnTest | Get-View
#$esxView = Get-VMHost esx35-01.vitoolkit.local | Get-View
foreach ($f in (Import-Csv "C:\Test.csv"))
{
	$vmView = Get-View -ViewType VirtualMachine -Filter @{"Name"=$f.VMname}
	echo $vmView.Name
}
$arg = New-Object VMware.Vim.MethodActionArgument
#$arg.Value = $esxview.MoRef
$action = New-Object VMware.Vim.MethodAction
$action.Argument = $arg
$action.Name = "PowerOnVM_Task"
$scheduler = new-object VMware.Vim.OnceTaskScheduler
$scheduler.runat = (get-date).addminutes(5)
$task = New-Object VMware.Vim.ScheduledTaskSpec
$task.Action = $action
$task.Description = "Start a VM with a scheduled task."
$task.Enabled = $true
$task.Name = "Power On Virtual Machine"
$task.Scheduler = $scheduler
$scheduledTaskManager.CreateScheduledTask($vmView.MoRef, $task) 

Provided your CSV file looks like this:

VMname
vmname1
vmname2
vmname3


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

meistermn
Expert
Expert
Jump to solution

Thanks Luc . I have to more problems .

Firsts how to use RelocateVM_Task , is it the rightfor storage vmotion in th vc center task

$ma.Name = "RelocateVM_Task"

$relSpec = new VirtualMachineRelocateSpec()

$relSpec.diskMoveType = VirtualMachineRelocateDiskMoveOptions.moveChildMostDiskBacking

$relSpec.datastore = datastorenew

second : when the task is created, the time for all task is the same. Between VM1 task and Vm2 task should be 30 minutes.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Yes, the RelocateVM_Task is the correct method to use for svMotion.

You can keep the time in a variable and add 30 minutes for each invocation.

Something like this

$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

$timestart = (Get-Date).addminutes(5)
$timeoffset = 30

foreach ($f in (Import-Csv "C:\Test.csv"))
{
	$vmView = Get-View -ViewType VirtualMachine -Filter @{"Name"=$f.VMname}
	echo $vmView.Name

	$arg = New-Object VMware.Vim.MethodActionArgument
	$action = New-Object VMware.Vim.MethodAction
	$action.Argument = $arg
	$action.Name = "PowerOnVM_Task"
	$scheduler = new-object VMware.Vim.OnceTaskScheduler
	$scheduler.runat = $timestart
	$timestart = $timestart.addminutes($timeoffset)
	$task = New-Object VMware.Vim.ScheduledTaskSpec
	$task.Action = $action
	$task.Description = "Start a VM with a scheduled task."
	$task.Enabled = $true
	$task.Name = "Power On Virtual Machine"
	$task.Scheduler = $scheduler
	$scheduledTaskManager.CreateScheduledTask($vmView.MoRef, $task) 
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

meistermn
Expert
Expert
Jump to solution

Morning Luc, tried it . I changed the line , because the output shows, that schedule task name must be different. So I tried add $f or $timestart.

$si = get-view ServiceInstance

$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

$timestart = (Get-Date).addminutes(5)

$timeoffset = 30

foreach ($f in (Import-Csv "C:\Test.csv"))

{

$vmView = Get-View -ViewType VirtualMachine -Filter @{"Name"=$f.VMname}

echo $vmView.Name

$arg = New-Object VMware.Vim.MethodActionArgument

$action = New-Object VMware.Vim.MethodAction

$action.Argument = $arg

$action.Name = "PowerOnVM_Task"

$scheduler = new-object VMware.Vim.OnceTaskScheduler

$scheduler.runat = $timestart

$timestart = $timestart.addminutes($timeoffset)

$task = New-Object VMware.Vim.ScheduledTaskSpec

$task.Action = $action

$task.Description = "Start a VM with a scheduled task."

$task.Enabled = $true

$task.Name = "Power On Virtual Machine" + $f

$task.Scheduler = $scheduler

$scheduledTaskManager.CreateScheduledTask($vmView.MoRef, $task)

}

</code>

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ah, I forgot the unique Scheduled Task names.

Should work with

...
$task.Name = "Power On Virtual Machine" + $f.VMname
...


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
meistermn
Expert
Expert
Jump to solution

How can the $task variable get the value from VirtualMachineRelocateSpec

$ma.Name = "RelocateVM_Task"

$datastorenew = datastorenew

$relSpec = new VirtualMachineRelocateSpec()

$relSpec.diskMoveType = VirtualMachineRelocateDiskMoveOptions.moveChildMostDiskBacking

$relSpec.datastore = $datastorenew

Reply
0 Kudos
meistermn
Expert
Expert
Jump to solution

the Data Object - ScheduledTaskSpec has no locatio or datastore property.

http://pubs.vmware.com/vi-sdk/visdk250/ReferenceGuide/vim.scheduler.ScheduledTaskSpec.html

Reply
0 Kudos
meistermn
Expert
Expert
Jump to solution

do i need VirtualMachineRelocateSpec

and VirtualMachineCloneSpec

Reply
0 Kudos
meistermn
Expert
Expert
Jump to solution

LUCD an idea

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

If I understood correctly you want to create a number of scheduled tasks, where each scheduled task will "migrate" a guest.

In the scheduled task I think you can't use the MethodAction for migrating a guest.

The MethodAction type only supports the same options you see in the vSphere Client ().

The only option I see is to use the RunScriptAction.

That would allow you to start a script that does the "migration" of the script.

What I would do:

- create a "migration" script that accepts some parameters (guestname, destination host, destination datastore)

- loop through the guests in your CSV file

- for each guest create a scheduled task with a RunScriptAction

- in the RunScriptAction you call the "migration" script with the correct parameters

What do you think ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
meistermn
Expert
Expert
Jump to solution

Hi LucD,

yes, i wanted to create a number of scheduled taks, where each scheduled task will migrate a guest.

When creating a schedule task in the gui from the vsphere client and choosing the option "migrate a virtual machine" (look at figure 1) then after choosing a vm, the screen "selects migration type" comes with two options host and datastore (look at figure 2).

It is the datastore option, which is storage vmotion. If the methodaction type supports the same options as in the vsphere client, I thought the different to the poweron schedule script is only the two parameters relocate and one more parameter for destination.

So can the migrate a virtual machine from schedule task of vc with datastore like in the figure 1 and figure shown be scripted. On the left side of the figure there are several steps starting with "select virtual machine", "select migration type, select "resource pool" , "select datstore and so on.

Figure 1

Figure 2

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You're right, must have missed that option Smiley Sad

Let me have a look, I'll get back to you.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The following script should do the trick.

$csvName = <CSV-file>
$tgtDatastore = <datastore-name>
$emailAddr = <email-address> 
$startTime = <start-datetime>	             # Ex [Datetime]"10/21/2009 20:00"
$startInterval = <minutes-between>

$si = get-view ServiceInstance
$scheduledTaskManager = Get-View $si.Content.ScheduledTaskManager

$offset = 0
Import-Csv $csvName | % {
	$vm = Get-View -ViewType VirtualMachine -Filter @{"Name"=$_.VMname}

	$spec = New-Object VMware.Vim.ScheduledTaskSpec
	$spec.Name = "svMotion " + $_.VMname
	$spec.Description = "Migrate " + $_.VMname + " to " + $tgtDatastore
	$spec.Enabled = $true
	$spec.Notification = $emailAddr
	$spec.Scheduler = New-Object VMware.Vim.OnceTaskScheduler
	$spec.Scheduler.runat = $startTime.AddMinutes($offset)
	$offset += $startInterval
	$spec.Action = New-Object VMware.Vim.MethodAction
	$spec.Action.Name = "RelocateVM_Task"

	$arg1 = New-Object VMware.Vim.MethodActionArgument
	$arg1.Value = New-Object VMware.Vim.VirtualMachineRelocateSpec
	$arg1.Value.datastore = (Get-Datastore $tgtDatastore | Get-View).MoRef
 	$arg1.Value.pool = $vm.ResourcePool
 	$arg1.Value.host = $vm.Runtime.Host

	$spec.Action.Argument += $arg1
	$arg2 = New-Object VMware.Vim.MethodActionArgument
	$arg2.Value = [http://VMware.Vim.VirtualMachineMovePriority|http://VMware.Vim.VirtualMachineMovePriority]"defaultPriority"
	$spec.Action.Argument += $arg2
	
	$scheduledTaskManager.CreateScheduledTask($vm.MoRef, $spec) 
}

Allthough the scheduled task will trigger a svMotion, the CreateScheduledTask method still seems to require a host and resourepool MoRef in the VirtualMachineRelocateSpec argument.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you want to learn a bit more of the internals of the MethodAction have a look at Scheduled Tasks – MethodAction


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
meistermn
Expert
Expert
Jump to solution

Hello Lucd,

tried in an othe cluster and geht following error message:

Ausnahme beim Aufrufen von "CreateScheduledTask" mit 2 Argument(en): "entity"

At :line:36 char:42

+ $scheduledTaskManager.CreateScheduledTask &lt;&lt;&lt;&lt; ($vm.MoRef, $spec)

WHat does it mean ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Are both clusters running under the same version of Virtual Center/vCenter ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
meistermn
Expert
Expert
Jump to solution

Yes.

After I closed powerGui Script editor and then opened the ps script again, it worked . Strange.

So I think at to do with my powergui script editor.

Lucd this script is super super super !!!!

Improvements 1: Read destination from csv file per vm

create a second column in the csv file for the destination datastore.

read from the script the destinantion datastore in the variabele $

Improvments 2:

Some VM's harddisk files are located on two different source datastores and through migration will be migrated to one destination datasource.

Reply
0 Kudos
meistermn
Expert
Expert
Jump to solution

How the following be combined with our script?

  1. With the new Import-CSV (only in Powershell Version 2) we can tell the cmdlet that we're using the semicolon as the field delimiter

$csv_info = Import-Csv "D:\MigrateStorage\cas2-charge1.csv" -delimiter ";"

 

foreach ($line in $csv_info) {

*

write-host " This is virtual machine $($line.VMname) and migrates to datastores $($line.Datastores)"

*

}

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can also use the -UseCulture parameter then the Import-Csv will use the seperator you have defined in your regional settings.

Try the attached version. It should do the trick.

The CSV file should look like this

VMname,Datastore
PC1,datastore1
PC2,datastore2


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos