Hyper-V中C#调用PowerShell遍历VM网卡类型转换问题求助
解决Hyper-V虚拟机网卡遍历的类型转换问题
我来帮你搞定这个问题,之前处理Hyper-V PowerShell对象转换时也踩过类似的坑~你遇到的核心问题是:NetworkAdapters属性返回的是一个集合对象,不是单个PSObject,所以直接强转PSObject肯定会失败。下面给你两种可行的解决方案:
方案1:通用枚举法(无需额外引用程序集)
如果不想依赖Hyper-V特定的程序集,这种方法最稳妥。我们先把属性值转成IEnumerable,然后遍历每个元素再转成PSObject,就能访问网卡的各项属性了:
var ps = PowerShell.Create(); ps.AddCommand("Get-VM"); foreach (PSObject vmObj in ps.Invoke()) { // 先将NetworkAdapters的值转换为可枚举集合 var networkAdapters = vmObj.Properties["NetworkAdapters"].Value as IEnumerable; if (networkAdapters != null) { foreach (var adapterItem in networkAdapters) { // 将每个网卡项转换为PSObject,进而访问属性 var adapterPsObj = adapterItem as PSObject; if (adapterPsObj != null) { // 示例:获取网卡名称、MAC地址 string adapterName = adapterPsObj.Properties["Name"].Value?.ToString(); string macAddress = adapterPsObj.Properties["MacAddress"].Value?.ToString(); // 这里填充你的自定义模型对象 // YourNetworkAdapterModel model = new YourNetworkAdapterModel // { // AdapterName = adapterName, // MacAddress = macAddress // }; } } } }
方案2:强类型转换法(需引用Hyper-V程序集)
如果你的项目可以引用Hyper-V的PowerShell管理程序集(Microsoft.HyperV.PowerShell.dll),可以直接强转成对应的泛型列表类型,这样就能用强类型属性访问,代码更简洁:
- 首先在项目中添加对
Microsoft.HyperV.PowerShell.dll的引用(通常位于C:\Windows\assembly路径下); - 使用以下代码:
var ps = PowerShell.Create(); ps.AddCommand("Get-VM"); foreach (PSObject vmObj in ps.Invoke()) { // 直接强转为Hyper-V的VMNetworkAdapter列表 var adapterList = vmObj.Properties["NetworkAdapters"].Value as List<Microsoft.HyperV.PowerShell.VMNetworkAdapter>; if (adapterList != null) { foreach (var adapter in adapterList) { // 直接访问强类型属性,无需再处理PSObject string adapterName = adapter.Name; string macAddress = adapter.MacAddress; // 填充你的模型对象 } } }
关键说明
你之前的代码失败,是因为NetworkAdapters属性返回的是System.Collections.Generic.List<Microsoft.HyperV.PowerShell.VMNetworkAdapter>集合,而不是单个PSObject。所以必须先把它当成集合来处理,再逐个访问里面的网卡对象。
内容的提问来源于stack exchange,提问作者user1403598
相关产品推荐
相关产品推荐

