Reputation: 13
I'm working on a WMI with Delphi, the goal is to set a VM IP with WMI. But something is going wrong on PUT.
The ConnectServer function is connecting to local Hyper-V Host as administrator.
Already had success working with powershell using the code:
Invoke-Command -ComputerName $VMhost -ArgumentList $IPaddress, $Mask, $Gatew, $VMname -ScriptBlock {
[string]$VMname = $args[3]
$VMManServ = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemManagementService
$vm = Get-WmiObject -Namespace 'root\virtualization\v2' -Class 'Msvm_ComputerSystem' | Where-Object { $_.ElementName -eq $VMname }
$vmSettings = $vm.GetRelated('Msvm_VirtualSystemSettingData') | Where-Object { $_.VirtualSystemType -eq 'Microsoft:Hyper-V:System:Realized' }
$nwAdapters = $vmSettings.GetRelated('Msvm_SyntheticEthernetPortSettingData')
$ipstuff = $nwAdapters.getrelated('Msvm_GuestNetworkAdapterConfiguration')
$ipstuff.DHCPEnabled = $false
$ipstuff.DNSServers = $args[2]
$ipstuff.IPAddresses = $args[0]
$ipstuff.Subnets = $args[1]
$ipstuff.DefaultGateways = $args[2]
$VMManServ.SetGuestNetworkAdapterConfiguration($VM, $ipstuff.GetText(1))
}
Now i'm working on a solution to integrate with a delphi application. After run, the app display success but nothing happens to the VM
procedure TForm2.SetNetworkAdapterConfiguration;
var
FSWbemLocator: ISWbemLocator;
FWMIService: ISWbemServices;
FWbemObjectSet: ISWbemObjectSet;
NetworkAdapterConfig: ISWbemObject;
ReturnValue: ISWbemObjectPath;
begin
try
FSWbemLocator := CoSWbemLocator.Create;
FWMIService := FSWbemLocator.ConnectServer('', 'root\virtualization\v2', '', '', '', '', 0, nil);
FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Msvm_GuestNetworkAdapterConfiguration WHERE InstanceID = "Microsoft:GuestNetwork\\CE89678D-73B0-4957-B7BF-73A42ABEDB52\\4FC2700C-A2F3-438A-80FB-078FDB33E67D"', 'WQL', 0, nil);
if not Assigned(FWbemObjectSet) or (FWbemObjectSet.Count = 0) then
begin
ShowMessage('Config not found.');
Exit;
end;
NetworkAdapterConfig := FWbemObjectSet.ItemIndex(0) as ISWBemObject;
Log1(FWbemObjectSet.ItemIndex(0).GetObjectText_(1));
NetworkAdapterConfig.Properties_.Item('DHCPEnabled', 0).Set_Value(OleVariant(False));
NetworkAdapterConfig.Properties_.Item('DNSServers', 0).Set_Value(VarArrayOf(['8.8.8.8']));
NetworkAdapterConfig.Properties_.Item('IPAddresses', 0).Set_Value(VarArrayOf(['192.168.0.199']));
NetworkAdapterConfig.Properties_.Item('Subnets', 0).Set_Value(VarArrayOf(['255.255.255.0']));
NetworkAdapterConfig.Properties_.Item('DefaultGateways', 0).Set_Value(VarArrayOf(['192.168.0.1']));
Log2(NetworkAdapterConfig.GetObjectText_(1));
ReturnValue := NetworkAdapterConfig.Put_(1, nil);
ShowMessage('Success.');
Log3(ISWbemObjectPathVarDump(ReturnValue));
except
on E: Exception do
ShowMessage('Error: ' + E.Message);
end;
end;
Result of the Logs:
Log1;
instance of Msvm_GuestNetworkAdapterConfiguration
{
DefaultGateways = {"192.168.0.1"};
DHCPEnabled = TRUE;
DNSServers = {"192.168.0.15"};
InstanceID = "Microsoft:GuestNetwork\\CE89678D-73B0-4957-B7BF-73A42ABEDB52\\4FC2700C-A2F3-438A-80FB-078FDB33E67D";
IPAddresses = {"192.168.0.162"};
IPAddressOrigins = {1};
ProtocolIFType = 4096;
Subnets = {"255.255.255.0"};
};
Log2;
instance of Msvm_GuestNetworkAdapterConfiguration
{
DefaultGateways = {"192.168.0.1"};
DHCPEnabled = FALSE;
DNSServers = {"8.8.8.8"};
InstanceID = "Microsoft:GuestNetwork\\CE89678D-73B0-4957-B7BF-73A42ABEDB52\\4FC2700C-A2F3-438A-80FB-078FDB33E67D";
IPAddresses = {"192.168.0.199"};
IPAddressOrigins = {1};
ProtocolIFType = 4096;
Subnets = {"255.255.255.0"};
};
Log3 Put_ result as ISWbemObjectPath;
\\.\root\virtualization\v2:Msvm_GuestNetworkAdapterConfiguration.InstanceID="Microsoft:GuestNetwork\\CE89678D-73B0-4957-B7BF-73A42ABEDB52\\4FC2700C-A2F3-438A-80FB-078FDB33E67D"
RelPath : Msvm_GuestNetworkAdapterConfiguration.InstanceID="Microsoft:GuestNetwork\\CE89678D-73B0-4957-B7BF-73A42ABEDB52\\4FC2700C-A2F3-438A-80FB-078FDB33E67D"
Server : .
Namespace : root\virtualization\v2
ParentNamespace : root\virtualization
DisplayName : WINMGMTS:{authenticationLevel=pktPrivacy,impersonationLevel=impersonate}!\\.\root\virtualization\v2:Msvm_GuestNetworkAdapterConfiguration.InstanceID="Microsoft:GuestNetwork\\CE89678D-73B0-4957-B7BF-73A42ABEDB52\\4FC2700C-A2F3-438A-80FB-078FDB33E67D"
Class_ : Msvm_GuestNetworkAdapterConfiguration
Locale :
Authority :
Edit: DHCP is not a option, i have to designate dynamically a already existing machine to a ip and vlan without dhcp server.
Edit2: https://learn.microsoft.com/en-us/windows/win32/wmisdk/swbemobject-put-
objObjectPath = .Put_( _
[ ByVal iFlags ], _
[ ByVal objwbemNamedValueSet ] _
)
Looking at docs, found something about the parameters of put_:
wbemChangeFlagUpdateOnly (1 (0x1))
objwbemNamedValueSet [in, optional]
Return value objObjectPath If the call is successful, an SWbemObjectPath object is returned. This object contains the object path of the instance or class that has been successfully committed to WMI.
by var dumping the object returned of put_, he returned a fully qualified SWbemObjectPath, check Log3 above;
Unfortunately still not applying to the Virtual Machine
Edit 4
By tracing WMI-Activity, i can see the put event being executed on Hyper-V Server Start IWbemServices::PutInstance
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Microsoft-Windows-WMI-Activity" Guid="{1418ef04-b0b4-4623-bf7e-d74ab47bbdaa}" />
<EventID>11</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x8000000000000000</Keywords>
<TimeCreated SystemTime="2024-05-02T23:35:42.7638600Z" />
<EventRecordID>65</EventRecordID>
<Correlation ActivityID="{1420ec18-2615-476a-bf58-c7fae612f136}" />
<Execution ProcessID="1748" ThreadID="3556" />
<Channel>Microsoft-Windows-WMI-Activity/Trace</Channel>
<Computer>HP006-SRV.MY_FQDN.com</Computer>
<Security />
</System>
- <UserData>
- <Operation_New xmlns="http://manifests.microsoft.com/win/2006/windows/WMI">
<CorrelationId>{00000000-0000-0000-0000-000000000000}</CorrelationId>
<GroupOperationId>335934</GroupOperationId>
<OperationId>335952</OperationId>
<Operation>Start IWbemServices::PutInstance - root\virtualization\v2 : Msvm_GuestNetworkAdapterConfiguration.InstanceID="Microsoft:GuestNetwork\\CE89678D-73B0-4957-B7BF-73A42ABEDB52\\4FC2700C-A2F3-438A-80FB-078FDB33E67D"</Operation>
<ClientMachine>NOTEHP-SRV</ClientMachine>
<ClientMachineFQDN>HP006-SRV.MY_FQDN.com</ClientMachineFQDN>
<User>MYDOMAIN\MY_USERNAME</User>
<ClientProcessId>3852</ClientProcessId>
<ClientProcessCreationTime>133591663144112869</ClientProcessCreationTime>
<NamespaceName>\\.\root\virtualization\v2</NamespaceName>
<IsLocal>true</IsLocal>
</Operation_New>
</UserData>
</Event>
Upvotes: 0
Views: 162
Reputation: 13
The solution was to follow the flow of the powershell script, and the ISWbemObjectEx object use.
FSWbemLocator := CoSWbemLocator.Create;
FWMIService := FSWbemLocator.ConnectServer('', nameSpace.text, '', '', '', '', 0, nil) ;
FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Msvm_VirtualSystemManagementService', 'WQL', 0, nil);
FWbemObjectSet2 := FWMIService.ExecQuery('SELECT * FROM Msvm_GuestNetworkAdapterConfiguration WHERE InstanceID LIKE "'+NetworkID.text+'"', 'WQL', 0, nil);
FWbemObjectSet3 := FWMIService.ExecQuery('SELECT * FROM Msvm_ComputerSystem WHERE ElementName LIKE "'+vmName.Text+'"', 'WQL', 0, nil);
VSMS := FWbemObjectSet.ItemIndex(0) as ISWbemObject;
NetAdapter := FWbemObjectSet2.ItemIndex(0) as ISWbemObjectEx;
VM := FWbemObjectSet3.ItemIndex(0) as ISWbemObject;
NetAdapter.Properties_.Item('IPAddresses', 0).Set_Value(VarArrayOf([IPAddress.Text]));
NetworkConfigurationArray := VarArrayCreate([0, 0], varOleStr);
NetworkConfigurationArray[0] := NetAdapter.GetText_(1,0,nil);
InParameters := VSMS.Methods_.Item('SetGuestNetworkAdapterConfiguration',0).InParameters.SpawnInstance_(0);
InParameters.Properties_.Item('ComputerSystem', 0).Set_Value(VM.Path_.Path);
InParameters.Properties_.Item('NetworkConfiguration',0).Set_Value(NetworkConfigurationArray);
VSMS.ExecMethod_('SetGuestNetworkAdapterConfiguration', InParameters, 0, nil);
Upvotes: 0