Reputation: 70
I am using Microsoft.Management.Infrastructure
to interface with WMI through C#. I am specifically trying to create a new VM through Hyper-V utilizing the Hyper-V WMI Provider (v2). One of the required WMI objects to pass to the DefineSystem
method is Msvm_VirtualSystemSettingData
, and I am trying to create a new instance of one while also inheriting the property and method definitions from the class prototype.
In this documentation page, Microsoft suggests that simply creating a new CimInstance
with the appropriate class name and namespace will automatically populate the instance with class information but no instance data.
CimInstance tempInstance = new("Msvm_VirtualSystemSettingData", "root\\virtualization\\v2");
Console.WriteLine(tempInstance.CimClass.CimClassProperties.Count());
0
This appears to be incorrect. The instance's CimClass.CimClassProperties
, CimClass.CimClassQualifiers
, and CimClass.CimClassMethods
are empty when inspecting the instance in the debugger. My expectation is that the CimInstance would be populated with properties/methods as defined here. Then I would be able to modify any that I need changing from whatever default values.
When researching this issue, I have tried following the advice outlined in this SO post, which recommends that you need to get the 'filled out' instance from a CimSession, where you fill out all KEY qualified parameters first.
So for Msvm_VirtualSystemSettingData
, there is a single KEY attribute named "InstanceID". I believe the correct input for this is as follows:
CimSession session = CimSession.create(null); // localhost
CimInstance tempInstance = new("Msvm_VirtualSystemSettingData", "root\\virtualization\\v2");
tempInstance.CimInstanceProperties.Add(CimProperty.Create("InstanceID", "Microsoft:Definition\\\\VirtualSystem\\\\VirtualSystemSubType\\\\Microsoft:Hyper-V:SubType:2", CimType.String, CimFlags.Key));
CimInstance realInstance = session.GetInstance("root\\virtualization\\v2", tempInstance);
session.Dispose();
The session.GetInstance()
call results in a Microsoft.Management.Infrastructure.CimException: 'Not found '
, which seems to imply that no instance exists from the given tempInstance reference.
Upvotes: 0
Views: 241
Reputation: 70
Here's a solution that does work, but has caveats.
CimSession session = CimSession.Create(null);
CimClass systemClass = session.GetClass(@"root\virtualization\v2", "Msvm_VirtualSystemSettingData");
CimInstance newInstance = new(systemClass);
The caveats are that no key properties are assigned. This seems to mean there is no relative or fully qualified path available to locate this new resource. It is not clear to me how InstanceID's are assigned to CIM instances, but creating a CimInstance in this way is not correct since not all KEY properties are defined.
Passing this incomplete CimInstance to the DefineSystem method (using InvokeMethod) does create a VM. Interestingly, the resultant Msvm_ComputerSystem that is returned, and indeed, all Msvm_ComputerSystem instances that exist in general (including Hyper-V Manager created ones) ALSO do not have their key parameters filled out, meaning they do not have resolvable WMI paths either!
This path issue is problematic because certain WQL queries require valid ObjectPath's, such as ASSOCIATORS OF clauses.
Edit: Here's another way to replicate the above behavior, but more WQL based:
CimSession session = CimSession.Create(null);
CimInstance newInstance = session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM meta_class WHERE __class = 'Msvm_VirtualSystemSettingData'").First();
Upvotes: 0