How to fix the error that calls AddMember() to return "WBEM_E_INVALID_METHOD_PARAMETERS"?

0

I use the powershell script below to give the virtual machine a snapshot of the rct.

$vm1 = Get-WmiObject -ns root\Virtualization\v2 Msvm_ComputerSystem |?{$_.elementname -eq "backup_test4"}
$cms = Get-WmiObject -ns root\Virtualization\v2 Msvm_CollectionManagementService
$result = $cms.DefineCollection("rcttest", $null, 0)
$coll = [wmi]$result.DefinedCollection
$result = $cms.AddMember($vm1, $coll)
$csss = Get-WmiObject -ns root\Virtualization\v2 Msvm_CollectionSnapshotService                                         
$result = $csss.CreateSnapshot([string]$coll, $null, 32768, $null)

It can generate snapshots normally. Therefore, I am going to refactor with C++. My code snippet is as follows:

HRESULT hresult = E_FAIL;
BSTR collectionClass = L"Msvm_CollectionManagementService";
IWbemClassObject* pInClass = NULL;
IWbemClassObject* pOutClass = NULL;
hresult = m_pWbemServices->GetObject(collectionClass,
    0,
    NULL,
    &m_pWbemClassObject,
    NULL);
if (FAILED(hresult)){
    string msg = "Failed to get object.";
    throw std::exception(msg.c_str());
}
// define collection
BSTR methodName1 = L"DefineCollection";
hresult = m_pWbemClassObject->GetMethod(
    methodName1,
    0,
    &pInClass,
    &pOutClass);
if (FAILED(hresult)){
    string msg = "Failed to get method";
    throw std::exception(msg.c_str());
}

According to the usage of DefineCollection()enter link description here, you need to set three three parameters for it, Collection name, GUID and Type. The code snippet is as follows:

//set param 
VARIANT var;
BSTR paramName1 = L"Name";
var.vt = VT_BSTR;
var.bstrVal = _bstr_t(_collectionName.c_str());

hresult = pInClass->Put(paramName1,
    0,
    &var,
    0);
if (FAILED(hresult)){
    string msg = "Failed to set property.";
    throw std::exception(msg.c_str());
}

BSTR paramName2 = L"Id";
var.vt = VT_BSTR;
var.bstrVal = _bstr_t("");
hresult = pInClass->Put(paramName2,
    0,
    &var,
    0);
if (FAILED(hresult)){
    string msg = "Failed to set property.";
    throw std::exception(msg.c_str());
}

BSTR paramName3 = L"Type";
var.vt = VT_I2;
var.iVal = (uint16_t)0;
if (FAILED(hresult)){
    string msg = "Failed to set property.";
    throw std::exception(msg.c_str());
}

string SqlStr = "SELECT * FROM Msvm_CollectionManagementService";
cout << "sqlstr:" << SqlStr << endl;
IEnumWbemClassObject* pEnumerator = doExecQuery(SqlStr);

IWbemClassObject *pClassObj = NULL;
ULONG uReturn = 0;

    while (1){
        hresult = pEnumerator->Next(
            WBEM_INFINITE,
            1,
            &pClassObj,
            &uReturn);

        if (FAILED(hresult)){
            string msg = "Failed to get computer system.";
            throw std::exception(msg.c_str());
        }
        break;
    }
    if (!pClassObj){
        string msg = "The virtual machine was not found.";
        throw std::exception(msg.c_str());
    }
    pClassObj->Get(L"__Path", 0, &var, 0, 0);

//invoke method
hresult = m_pWbemServices->ExecMethod(
    var.bstrVal,
    methodName1,
    0,
    NULL,
    pInClass,
    &pOutClass,
    NULL);
if (FAILED(hresult)){
    string msg = "Failed to invoke method.";
    throw std::exception(msg.c_str());
}

According to the usage and script of AddMember()enter link description here, I need to add two parameters,Member and Collection. I did this.

VARIANT var;
BSTR paramName4 = L"Member";
//var.vt = VT_BYREF | VT_UNKNOWN;
//var.ppunkVal = (IUnknown**)m_pComputerSystem;
var.vt = VT_BYREF;
var.byref = (PVOID)m_pComputerSystem;
//var.vt = VT_UNKNOWN;
//var.punkVal = (IUnknown*)pInClass;

hresult = pInClass->Put(paramName4,
    0,
    &var,
    0);
if (FAILED(hresult))
{
    string msg = "Failed to set property.";
    throw std::exception(msg.c_str());
}

BSTR paramName5 = L"Collection";
//var.vt = VT_BYREF | VT_UNKNOWN;
//var.ppunkVal = (IUnknown**)&collectionName;
//var.vt = VT_BYREF;
//var.byref = (PVOID)collectionName;
var.vt = VT_UNKNOWN;
var.punkVal = (IUnknown*)collectionName;
hresult = pInClass->Put(paramName5,
    0,
    &var,
    0);
if (FAILED(hresult))
{
    string msg = "Failed to set property.";
    throw std::exception(msg.c_str());
}

string SqlStr = "SELECT * FROM Msvm_CollectionManagementService";
cout << "sqlstr:" << SqlStr << endl;
IEnumWbemClassObject* pEnumerator = doExecQuery(SqlStr);

IWbemClassObject *pClassObj = NULL;
ULONG uReturn = 0;

while (1)
{
    hresult = pEnumerator->Next(
        WBEM_INFINITE,
        1,
        &pClassObj,
        &uReturn);

    if (FAILED(hresult))
    {
        string msg = "Failed to get computer system.";
        throw std::exception(msg.c_str());
    }
    break;
}
if (!pClassObj)
{
    string msg = "The virtual machine was not found.";
    throw std::exception(msg.c_str());
}
pClassObj->Get(L"__Path", 0, &var, 0, 0);

//invoke method
hresult = m_pWbemServices->ExecMethod(
    var.bstrVal,
    methodName2,
    0,
    NULL,
    pInClass,
    &pOutClass,
    NULL);
if (FAILED(hresult))
{
    string msg = "Failed to invoke method.";
    throw std::exception(msg.c_str());
}

The return value of each execution of ExecMethod() is 2147749935 (0x8004102F). According to MSDN's description of the AddMember() parameter, I didn't really understand what Member and Collection are. I passed those two parameters. It should be really wrong, but I can't find it. Please give me some guidance, thank you

c++
wmi
hyper-v
asked on Stack Overflow Apr 17, 2019 by Chaplin Hwang • edited Apr 17, 2019 by Chaplin Hwang

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0