Hi there,
I'm trying to move a Vmware.Vim.VirtualMachine from one Vmware.Vim.Folder to another with the API Provided by the C# Vmware.Vim.dll from the
PowerCLI in a VisualStudio 2010 Project. Please be aware that these Folders are not "normal" Folders, these are the VMware containers...
Could someone tell me how to achieve this?
I found the vm.Relocate_Task() Method, but I was wondering wether it was for moving the disks in storage or should it be used for this task too?
Greetings,
Kjellski
That's correct, a vApp is treated as a type of ResourcePool, so the MoveIntoResourcePool() - http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ResourcePool.html#moveIn... is what you'll want to use. Unfortunately this is not an async operation, so you will be be blocked until the operation completed but this should be pretty quickly and if any faults are thrown, the operation will terminate.
I would highly recommend taking a look at VMware Onyx, this is allows you to literally perform an operation using the vSphere Client and the appropriate SOAP, C# or PowerCLI code is generated so you can easily see what methods are being used for what operation. This is really useful in troubleshooting and figuring out what paramters are needed for a particular operation.
As you go out and ask somebody, you discover new ideas of trying...
Could it be that I need to use the Folder object and tell it to move somethings into itself?
using Vmware.Vim;
class VMAbstraction {
...
public Task moveTo(ManagedObjectReference targetFolder)
{
// vmc is the Vmware.Vim.VimClient
Folder f = new Folder(vmc, targetFolder);
return new Task(vmc, f.MoveIntoFolder_Task(new ManagedObjectReference[] { vm.MoRef }));}
...
}
That's correct, you'll need to use the MoveIntoFolder_Task() - http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.Folder.html#moveInto
An what is the correct way to move a VirtualMachine from one VirtualApp to another, or from a RessourcePool to another?
For a RessourcePool, which is in this case the same things as a VirtualApp if I get the documentation right, there is just the Blocking, no Task returning method MoveIntoResourcePool(). Could I create my own task in order to keep it Async?
I couldn't find a Method on the VirtualMachine side, which would generalize what I want...
My problem is that I don't get arround the idea of sticking every API call to the target side and implement is so often... but that is not your problem
That's correct, a vApp is treated as a type of ResourcePool, so the MoveIntoResourcePool() - http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ResourcePool.html#moveIn... is what you'll want to use. Unfortunately this is not an async operation, so you will be be blocked until the operation completed but this should be pretty quickly and if any faults are thrown, the operation will terminate.
I would highly recommend taking a look at VMware Onyx, this is allows you to literally perform an operation using the vSphere Client and the appropriate SOAP, C# or PowerCLI code is generated so you can easily see what methods are being used for what operation. This is really useful in troubleshooting and figuring out what paramters are needed for a particular operation.
Hi again lawm,
just wanted to say thanks again, and thanks for mentioning the Onyx Project which is really helpful.
Greetings,
Kjellski
public static void CreateFolder(VimClient client, string foldername, params string[] vmNames)
{
// ------- CreateFolder -------
Folder _this = new Folder(client, new ManagedObjectReference("Folder-group-v3"));
_this.CreateFolder(foldername);
// ------- MoveIntoFolder_Task -------
foreach (string t in vmNames)
{
var filter = new NameValueCollection { { "name", "^" + t + "$" } };
var vm = (VirtualMachine)client.FindEntityView(typeof(VirtualMachine), null, filter, null);
if (vm == null)
{
Console.WriteLine(t + " is not a valid virtual Machine name.");
}
else
{
ManagedObjectReference[] list = new ManagedObjectReference[1];
list[0] = new ManagedObjectReference {Type = "VirtualMachine", Value = vm.MoRef.Value};
ManagedObjectReference m = _this.MoveIntoFolder_Task(list);
}
}
}
In the above snippet, the virtual machines move but not to the folder specified, they stay where they are, i.e. within DC and the folder is empty after the operation. What am I missing?
New snippet that worked...but only once.. It doesn't like the hardcoded values such as new ManagedObjectReference("Folder-group-v470")); How can I make this dynamic?
public static void CreateFolder(VimClient client, string foldername, params string[] vmNames)
{
// ------- CreateFolder -------
Folder folder = new Folder(client, new ManagedObjectReference("Folder-group-v3"));
folder.CreateFolder(foldername);
// ------- MoveIntoFolder_Task -------
foreach (string t in vmNames)
{
var filter = new NameValueCollection { { "name", "^" + t + "$" } };
var vm = (VirtualMachine)client.FindEntityView(typeof(VirtualMachine), null, filter, null);
if (vm == null)
{
Console.WriteLine(t + " is not a valid virtual Machine name.");
}
else
{
ManagedObjectReference[] list = new ManagedObjectReference[1];
list[0] = new ManagedObjectReference {Type = "VirtualMachine", Value = vm.MoRef.Value};
Folder _this = new Folder(client, new ManagedObjectReference("Folder-group-v470"));
ManagedObjectReference m = _this.MoveIntoFolder_Task(list);
AwaitTaskCompletion(client, m);
}
}
}
Hi there vichlu,
I think there are some concepts that you've eventually missed on the run:
You could write one method that creates a Folder in a given one, returning that new Folder as a reference and then hand it to another methat that does the actual moving of the vm.
You could reuse the two method for all kind of things in the future and also bundle them with a wrapping method that you could call "createFolderAndMoveVMIntoIt(String newFolderName, ManagedObjectReference folderToCreateTheNewOneInReference, ManagedObjectReference virtualMchineReference)" for example.
For finding a Folder by Name, I use this code snippet:
System.Collections.Specialized.NameValueCollection filter = new System.Collections.Specialized.NameValueCollection(); filter.Add("name", name); Folder f = (Folder) vmc.FindEntityView(typeof(Folder), vmFolder, filter, null); if (f != null) { // Found it, now put it into the cache cache.Add(name, new RLFolder(f)); return new RLFolder(vmc, f.MoRef); } else { throw new RLVMwareWrapper.Exceptions.FolderNotFoundException("Couldn't find Folder: " + name); }
I hope this helps!
Greetings,
Kjellski
HI Kjellski
I just don't get it... where do I say where the VM shall be moved to? I mean don't I have to specify a path of something?
Can someone please make me a sample with names and everything?
And what is this ManagedObjectReference? This does not make sense to me since I dont see any path...
Thank you.