C# VMWare PowerCli 6.0 从文件夹启动虚拟机

C# VMWare PowerCli 6.0 Start-VM from a folder

如果这个问题已经得到回答,我很抱歉,我没有找到任何相关信息。

我正在为 vSphere 6 开发 PowerCLi 6.0。

我拥有特定文件夹(称为 "XXXFolder")的所有权限,但不是整个主机的权限。 在此文件夹中,我尝试使用 C# 自动执行 Power Off/On 操作。

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 方法,它将 VM 所在的主机作为参数。所以像 :

myVM.PowerOn(myVM.Runtime.Host);

但是因为我对主机没有权限(我只对 VM 所在的特定文件夹有权限),我异常退出并显示以下消息:

"Permission to perform this operation was denied."

请注意,使用以下 Powershell 命令可以正常工作:

Start-VM -VM $myVM

有人知道在 C# 中如何启动位于特定文件夹中的虚拟机吗?

非常感谢您的帮助。

你好@MikaTTC 你能尝试利用 PowerOnMultiVM_Task 来自数据中心对象的方法?我将你的情况转述如下: 做了新用户。 授予用户对 VM 文件夹的管理员访问权限。我在 VM 文件夹中放置了 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

既然您有客户端和 VM 对象,请使用以下命令启动 VM。通常在启动 VM 时,我会等待工具可用,然后再继续。

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());

感谢 Gregu,我解决了这个问题。这是用于启动位于文件夹中的 VM 的 C# 代码。 (PowerOnMultiVM_Task 不需要整个主机的权限)

请注意,在以下代码中,我删除了:

  • 条件(检查对象不为空,VM状态为关机状态),
  • 错误处理(Try/Catch)
  • 同步(等待任务)

为了让这部分代码更容易理解。

再次感谢@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);