【问题标题】:C# VMWare PowerCli 6.0 Start-VM from a folderC# VMWare PowerCli 6.0 从文件夹启动-VM
【发布时间】:2020-05-26 12:17:33
【问题描述】:

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

我正在为 vSphere 6 开发 PowerCLi 6.0。

我拥有特定文件夹(称为“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 方法,它将 VM 所在的主机作为参数。所以像:

myVM.PowerOn(myVM.Runtime.Host);

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

"Permission to perform this operation was denied."

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

Start-VM -VM $myVM

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

非常感谢您的帮助。

【问题讨论】:

    标签: c# vmware vsphere powercli


    【解决方案1】:

    你好@MikaTTC 你能尝试使用 来自数据中心对象的 PowerOnMultiVM_Task 方法?我将您的情况复制如下: 成为新用户。 授予用户对 VM 文件夹的管理员访问权限。我在 VM 文件夹中放了 1 个 vm。

    使用 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

    【讨论】:

    • 非常感谢您的宝贵时间,非常感谢。我现在正在以这种方式进行调查,即使我似乎没有对允许我使用此方法的 Dll 的引用。我会在接下来的几天在这里更新你。再次感谢
    • 嗨 Mika,我不是 c# 程序员或类似的人,但我试图为你找到这个。看一看 。您的 c# 客户端: $client = New-Object VMware.Vim.VimClientImpl ,那么您的数据中心对象是: $dc = $client.FindEntityView([VMware.Vim.Datacenter],[VMware.Vim.ManagedObjectReference]'Folder-group- d1', $null, $null); Folder-group-d1 是 VirtualCenter 主树。在此之后,您可以使用上述方法 poweronmultivm : $dc.PowerOnMultiVM 定义 PowerOnMultiVM(VMware.Vim.ManagedObjectReference[] vm, VMware.Vim.OptionValue[] option)
    • 嗨@Gregu,我非常非常非常感谢。感谢我解决了这个问题。数据中心对象的这种方法使操作成为可能。你让我走上了正确的轨道,并再次“谢谢你”。我为下一个遇到同样问题的人分享 C# 代码。干杯
    • @mikaTTC 很高兴我能帮上忙 ;) 其他的都做得很好!
    【解决方案2】:

    由于您拥有客户端和 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());
    

    【讨论】:

    • 感谢您提供帮助,但这与我的问题无关。我没有整个主机的权限,只有数据中心的特定文件夹。
    • 您甚至可以从 Web 或 UI 客户端启动虚拟机吗?我认为没有任何方法可以绕过允许您开机或关机的权限。您无需拥有 ESX 主机上的权限即可启动系统。只要您在 vCenter 中拥有允许您启动系统的权限即可。
    • 嗨。是的,我可以从 UI Vsphere 客户端打开/关闭电源。甚至可以使用 C# 关闭电源(提醒一下, myVM.PowerOffVM(); 工作正常,但 PowerOn 使用 myVM.Runtime.Host 作为参数,我没有全部权限,所以我退出了异常)。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 2014-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多