10

我想通过 WQL 查询获取引导硬盘的序列号。

可以使用以下查询检索引导分区:

SELECT * FROM Win32_DiskPartition where BootPartition=True

序列号在 Win32_DiskDrive 中:

SELECT DeviceID, SerialNumber FROM Win32_DiskDrive

Win32_DiskDriveToDiskPartition具有Win32_DiskDriveto的映射Win32_DiskPartition。它们映射Win32_DiskDrive.DeviceIDWin32_DiskPartition.DeviceIDWin32_DiskDriveToDiskPartition

如何构建一个内部连接Win32_DiskPartition和的 WQL 查询Win32_DiskDrive?我必须使用关联器还是与 INNER JOIN 一起使用?

4

2 回答 2

15

WQL 不支持该JOIN子句。您需要使用ASSOCIATORS OF您猜到的语句。这是 VBScript 中的一个示例:

strComputer = "." 
Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 

Set colPartitions = oWMI.ExecQuery( _
    "SELECT * FROM Win32_DiskPartition WHERE BootPartition=True") 

For Each oPartition in colPartitions 

    Set colDrives = oWMI.ExecQuery( _
        "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" _
        & oPartition.DeviceID & "'} WHERE ResultClass=Win32_DiskDrive")

    For Each oDrive in colDrives
        WScript.Echo oDrive.SerialNumber
    Next

Next

但是请注意,该Win32_DiskDrive.SerialNumber属性在 Windows Vista 之前不可用。因此,如果您希望您的代码也适用于早期的 Windows 版本(例如 Windows XP 或 Windows 2000),您应该考虑使用 WMI 以外的 API。


编辑:( 回复评论)可以,可以添加嵌套ASSOCIATORS OF查询来获取Win32_PhysicalMedia实例对应的Win32_DiskDrive实例;像这样的东西:

...
For Each oDrive in colDrives
    Set colMedia = oWMI.ExecQuery( _
        "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" _
        & oDrive.DeviceID & "'} WHERE ResultClass=Win32_PhysicalMedia")

    For Each oMedia in colMedia
        WScript.Echo oMedia.SerialNumber
    Next
Next

你还没有说你正在使用什么语言 - 我猜在 PowerShell 或 C# 中,整个事情可以更优雅地完成,但 VBScript 非常冗长。

于 2010-07-08T19:26:52.313 回答
10

这是与 Helen 发布的 VBScript 代码执行相同操作的 C++ 代码。

// Obtain the initial locator to WMI
// ...
// Connect to WMI through the IWbemLocator::ConnectServer method
// ...
// Set security levels on the proxy
// ...

wchar_t wmihddsn[256];
    *wmihddsn=0;

hres = pSvc->ExecQuery(
    bstr_t("WQL"),
    bstr_t("SELECT * FROM Win32_DiskPartition WHERE BootPartition=True"),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
    NULL,
    &pEnumerator);

if(SUCCEEDED(hres) && pEnumerator) 
{
    // get the first Win32_DiskPartition
    HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

    if(SUCCEEDED(hr) && 0 != uReturn)
    {
        VARIANT vtProp;
        wchar_t tmp[1024];
        char query[1024];

        // Get the value of the partition's DeviceID property
        hr = pclsObj->Get(L"DeviceID", 0, &vtProp, 0, 0);
        if(SUCCEEDED(hr))
        {
            if(vtProp.vt == VT_BSTR) {
                // wcout << " SerialNumber : " << vtProp.bstrVal << endl;
                wcscpy(tmp, vtProp.bstrVal);
            }
            VariantClear(&vtProp);


            // "join" Win32_DiskPartition to Win32_DiskDrive
            sprintf(query, 
                "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='%s'} WHERE ResultClass=Win32_DiskDrive",
                NarrowWcharString(tmp));

            hres = pSvc->ExecQuery(
                bstr_t("WQL"),
                bstr_t(query),
                WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
                NULL,
                &pEnumerator1);

            if(SUCCEEDED(hres) && pEnumerator1)
            {
                // get the first Win32_DiskDrive
                hr = pEnumerator1->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn);

                if(SUCCEEDED(hr) && 0 != uReturn)
                {
                    // Get the value of the disk-drive's DeviceID
                    hr = pclsObj1->Get(L"DeviceID", 0, &vtProp, 0, 0);
                    if(SUCCEEDED(hr))
                    {
                        if(vtProp.vt == VT_BSTR)
                        {
                            wcscpy(tmp, vtProp.bstrVal);
                        }
                        VariantClear(&vtProp);


                        // "join" Win32_DiskDrive to Win32_PhysicalMedia
                        sprintf(query,
                            "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='%s'} WHERE ResultClass=Win32_PhysicalMedia",
                            NarrowWcharString(tmp));

                        hres = pSvc->ExecQuery(
                            bstr_t("WQL"),
                            bstr_t(query),
                            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
                            NULL,
                            &pEnumerator2);

                        if(SUCCEEDED(hres) && pEnumerator2)
                        {
                            // get the first Win32_PhysicalMedia
                            hr = pEnumerator2->Next(WBEM_INFINITE, 1, &pclsObj2, &uReturn);

                            if(SUCCEEDED(hr) && 0 != uReturn)
                            {
                                // get the PhysicalMedia's SerialNumber
                                hr = pclsObj2->Get(L"SerialNumber", 0, &vtProp, 0, 0);
                                if(SUCCEEDED(hr))
                                {
                                    if(vtProp.vt == VT_BSTR) 
                                    {
                                        // wcout << " SerialNumber : " << vtProp.bstrVal << endl;
                                        wcscpy(wmihddsn,vtProp.bstrVal);
                                    }
                                    VariantClear(&vtProp);
                                }

                            }

                            if(pclsObj2) pclsObj2->Release();
                        }
                        if(pEnumerator2) pEnumerator2->Release();

                    } // get disk-drive's DeviceID
                }

                if(pclsObj1) pclsObj1->Release();
            }
            if(pEnumerator1) pEnumerator1->Release();

        } // get partition's DeviceID
    }

    if(pclsObj) pclsObj->Release();
} // if succeeded first query
if(pEnumerator) pEnumerator->Release();

// ...
// cleanup
于 2010-07-11T08:17:02.480 回答