如何使用C# .NET及VMware.Vim.dll在vSphere ESXi中创建虚拟机?
使用C# + VMware.Vim.dll 在vSphere ESXi中创建虚拟机
没问题,我来帮你补全用VMware.Vim.dll创建虚拟机的核心逻辑。你已经搞定了客户端连接和登录的部分,接下来只需要构建虚拟机的配置参数,调用vSphere API就能完成创建。咱先把完整的实现代码放出来,再拆解关键环节:
完整的VmCreator类实现
using VMware.Vim; using System; using System.Net; public class VmCreator { private VimClient _client; public VmCreator(string hostName, string username, string password) { _client = new VimClientImpl(); // 跳过自签名证书验证(生产环境建议配置可信证书后移除) ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; _client.Connect($"https://{hostName}/sdk"); _client.Login(username, password); } public ManagedObjectReference CreateVirtualMachine(string vmName, string datastoreName, string portGroupName) { // 1. 获取目标ESXi主机、资源池和存放VM的文件夹 var host = GetHostSystem(); var resourcePool = host.Parent as ResourcePool; var vmFolder = host.Parent.Parent as Folder; // 2. 构建虚拟机配置规格 var vmConfig = new VirtualMachineConfigSpec { Name = vmName, MemoryMB = 2048, // 分配2GB内存 NumCPUs = 2, // 分配2核CPU GuestId = "otherGuest", // 按需替换,比如"windows9_64Guest"对应Win10 Files = new VirtualMachineFileInfo { // 指定虚拟机文件存放路径 VmPathName = $"[{datastoreName}] {vmName}" }, // 配置磁盘和网络设备 DeviceChange = new VirtualDeviceConfigSpec[] { // 添加20GB磁盘 new VirtualDeviceConfigSpec { Operation = VirtualDeviceConfigSpecOperation.add, Device = new VirtualDisk { CapacityInBytes = 20L * 1024 * 1024 * 1024, Backing = new VirtualDiskFlatVer2BackingInfo { Datastore = GetDatastore(datastoreName), DiskMode = "persistent" }, ControllerKey = 1000, // 默认SCSI控制器Key UnitNumber = 0 } }, // 添加网络适配器 new VirtualDeviceConfigSpec { Operation = VirtualDeviceConfigSpecOperation.add, Device = new VirtualEthernetCard { Backing = new VirtualEthernetCardNetworkBackingInfo { Network = GetNetwork(portGroupName), DeviceName = portGroupName }, AddressType = "assigned" // 自动分配MAC地址 } } } }; // 3. 调用API发起创建任务 var task = _client.CreateVM_Task(vmConfig, vmFolder, resourcePool, host); // 4. 同步等待任务完成(异步场景可自行调整逻辑) WaitForTask(task); Console.WriteLine($"虚拟机 {vmName} 创建完成!"); return task.Result; } // 辅助方法:获取目标ESXi主机(默认取第一个,多主机环境可按需筛选) private HostSystem GetHostSystem() { var hosts = _client.FindEntityViews(typeof(HostSystem), null, null, null); return hosts[0] as HostSystem; } // 辅助方法:根据名称获取数据存储 private Datastore GetDatastore(string datastoreName) { var datastores = _client.FindEntityViews(typeof(Datastore), null, new NameValuePair[] { new NameValuePair("name", datastoreName) }, null); return datastores[0] as Datastore; } // 辅助方法:根据名称获取网络端口组 private Network GetNetwork(string portGroupName) { var networks = _client.FindEntityViews(typeof(Network), null, new NameValuePair[] { new NameValuePair("name", portGroupName) }, null); return networks[0] as Network; } // 辅助方法:等待vSphere任务完成,处理成功/失败状态 private void WaitForTask(ManagedObjectReference taskRef) { while (true) { var task = _client.GetView(taskRef, null) as Task; if (task.Info.State == TaskInfoState.success) break; if (task.Info.State == TaskInfoState.error) throw new Exception($"任务执行失败:{task.Info.Error.LocalizedMessage}"); System.Threading.Thread.Sleep(1000); } } // 使用完毕后断开连接 public void Disconnect() { _client.Logout(); _client.Disconnect(); } }
关键环节说明
- 证书处理:代码里的证书验证回调是为了适配ESXi默认的自签名证书,生产环境一定要配置可信证书后移除这段代码,避免安全风险。
- 虚拟机核心配置:
VirtualMachineConfigSpec是创建VM的核心载体,几乎所有VM参数(内存、CPU、GuestOS、磁盘、网络等)都在这里定义,GuestId可以参考VMware官方枚举值匹配你的目标系统。 - 异步任务处理:vSphere的创建操作是异步任务,
WaitForTask做了同步等待,如果你是Web应用或异步服务,可以改成异步等待或者监听任务事件。 - 资源定位:代码默认取第一个ESXi主机,集群环境下可以根据主机名称筛选目标节点,资源池和文件夹也可以按需指定。
注意事项
- 确保你的
VMware.Vim.dll版本和vSphere/ESXi版本兼容,避免API调用出现兼容性报错。 - 登录账号需要拥有创建虚拟机的权限(比如VMware的
VirtualMachine.Inventory.Create权限)。 - 数据存储和网络端口组的名称要和ESXi上的完全一致,否则会找不到对应的资源。
- 磁盘容量单位是字节,计算时要注意转换(比如20GB = 20 * 1024 * 1024 * 1024 字节)。
内容的提问来源于stack exchange,提问作者Danie
相关产品推荐
相关产品推荐

