C# VMWare PowerCli 6.0 Start-VM из папки - PullRequest
0 голосов
/ 26 мая 2020

Заранее прошу прощения, если на этот вопрос уже был дан ответ, я ничего об этом не нашел.

Я работаю над PowerCLi 6.0 для vSphere 6.

I иметь все разрешения для определенной папки c (называемой «XXXFolder»), но не для всего хоста. В этой папке я пытаюсь автоматизировать операции выключения / включения с помощью C#.

VMware.Vim.VimClientImpl myClient = new VimClientImpl();
myClient.Connect("https://" + hostName + ":443/sdk");
myClient.Login(userName, passWord);
NameValueCollection propertyFilter = new NameValueCollection();
propertyFilter.Add("name", "VMName");
VMware.Vim.VirtualMachine myVM = (VirtualMachine)myClient.FindEntityView(typeof(VirtualMachine), null, propertyFilter, null);   

Операция powerOff отлично работает следующим образом:

myVM.PowerOffVM();

Но для PowerOn , он принимает в качестве аргумента хост, на котором размещена виртуальная машина. Что-то вроде:

myVM.PowerOn(myVM.Runtime.Host);

Но поскольку у меня нет разрешений на хосте (напомню, только в указанной папке c, в которой находится виртуальная машина), я выхожу в исключение со следующим сообщением :

"Permission to perform this operation was denied."

Обратите внимание, что следующая команда Powershell отлично работает:

Start-VM -VM $myVM

Кто-нибудь знает в C#, как включить виртуальную машину, которая находится в определенном c папка?

Большое спасибо за помощь.

Ответы [ 3 ]

0 голосов
/ 13 июля 2020

Поскольку у вас есть клиент и объекты виртуальной машины, используйте следующее для запуска виртуальной машины. Обычно при включении виртуальной машины я жду, когда появятся инструменты, прежде чем продолжить.

myClient.WaitForTask(myVM.PowerOnVM_Task(myVM.Runtime.Host));
while (true) 
{
    // Get Fresh details of the VM
    VMware.Vim.VirtualMachine myVM = (VirtualMachine)myClient.FindEntityView(typeof(VirtualMachine), null, propertyFilter, null);
    if (!myVM.Guest.ToolsRunningStatus.Equals("guestToolsRunning"))
        Thread.Sleep(2000); // Wait 2 seconds and try again. (Changeable)
    else
        break;

    // Add another statement here that only loops through x amount of times before quiting tools status. 
    // You dont want to be stuck here forever
}

вы можете использовать тот же метод при выключении виртуальных машин,

myClient.WaitForTask(myVM.PowerOffVM_Task());
0 голосов
/ 14 июля 2020

Спасибо Грегу, проблему решил. Это код C# для включения виртуальной машины, расположенной в папке. (PowerOnMultiVM_Task не требует разрешений для всего хоста)

Обратите внимание, что в этом следующем коде я удалил:

  • условия (чтобы проверить, что объекты не пусты, а состояние виртуальной машины выключен),
  • обработка ошибок (Try / Catch)
  • Syn c (ожидание задачи)

, чтобы эта часть кода была более понятно.

СНОВА, Спасибо @ Gregu

    // dummy values examples
    string hostName = "10.0.0.20"; 
    string userName = "myUser"; 
    string sFolderName = "myFolderName"; 
    string sMyDataCenter = "myDataCenterName"; 
    string sMyVM = "sMyVMNAme"; 
    
    List<VMware.Vim.ManagedObjectReference> MOF = new List<VMware.Vim.ManagedObjectReference>();
    
    // Create Client Object
    VMware.Vim.VimClientImpl myClient = new VimClientImpl();
    
    // Connect to host
    myClient.Connect("https://" + hostName + ":443/sdk");
    myClient.Login(userName, passWord);
    
    // Create a Folder object which has the name defined
    NameValueCollection propertyFilterFolder = new NameValueCollection();
    propertyFilterFolder.Add("name", sFolderName);
    VMware.Vim.Folder myFolder = (Folder)myClient.FindEntityView(typeof(Folder), null, propertyFilterFolder, null);
    
    // Create a DataCenter object which has the name defined
    NameValueCollection propertyFilterDC = new NameValueCollection();
    propertyFilterDC.Add("name", sMyDataCenter);
    VMware.Vim.Datacenter myDC = (Datacenter)myClient.FindEntityView(typeof(Datacenter), null, propertyFilterDC, null);
    
    // Create a VM object which has the name defined (From the specified folder)
    NameValueCollection propertyFilter = new NameValueCollection();
    propertyFilter.Add("name", sMyVM);
    VMware.Vim.VirtualMachine myVMF = (VirtualMachine)myFolder.Client.FindEntityView(typeof(VirtualMachine), null, propertyFilter, null);
    
    MOF.Add(myVMF.MoRef);
    
    // Calling the Start VM method
    myDC.PowerOnMultiVM_Task(MOF.ToArray(), null);

0 голосов
/ 03 июля 2020

Привет @ MikaTT C вы можете попробовать использовать метод PowerOnMultiVM_Task, поступающий из объекта центра обработки данных? Я воспроизвел вашу ситуацию следующим образом: Создан новый пользователь. Пользователю предоставлен доступ администратора к папке виртуальной машины. Я поместил 1 виртуальную машину в папку виртуальной машины.

Используемый API для включения его с помощью:

$vm = New-Object VMware.Vim.ManagedObjectReference[] (1)
$vm[0] = New-Object VMware.Vim.ManagedObjectReference
$vm[0].Type = 'VirtualMachine'
$vm[0].Value = 'vm-82'
$DCView = Get-View -Id 'Datacenter-datacenter-2'
$DCView.PowerOnMultiVM_Task($vm, $null)

Я знаю, что это не c#, но я уверен, что вы можете это понять . Метод описан здесь https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.Datacenter.html

...