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);
如果这个问题已经得到回答,我很抱歉,我没有找到任何相关信息。
我正在为 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);