2010-07-08 10 views
9

Ich möchte die Seriennummer der Boot-Festplatte über eine WQL-Abfrage erhalten.So fügen Sie eine WMI-Abfrage (WQL) hinzu

SELECT * FROM Win32_DiskPartition where BootPartition=True 

Die Seriennummer ist in Win32_DiskDrive:

SELECT DeviceID, SerialNumber FROM Win32_DiskDrive 

Win32_DiskDriveToDiskPartition hat die Zuordnung von Win32_DiskDrive-Win32_DiskPartition

Die Boot-Partition kann mithilfe der folgenden Abfrage abgerufen werden. Sie sind Win32_DiskDrive.DeviceID zu Win32_DiskPartition.DeviceID in Win32_DiskDriveToDiskPartition

abgebildet Wie kann ich eine WQL-Abfrage bauen, dass innere Win32_DiskPartition und Win32_DiskDrive verbindet? Muss ich Associators verwenden oder funktioniert es mit INNER JOIN?

Antwort

13

WQL unterstützt die Klausel JOIN nicht. Sie müssen die ASSOCIATORS OF Anweisung verwenden, wie Sie erraten haben. Hier ist ein Beispiel in 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 

Beachten Sie jedoch, dass die Win32_DiskDrive.SerialNumber Eigenschaft nicht verfügbar ist vor Windows Vista. Wenn Sie möchten, dass Ihr Code auch auf früheren Windows-Versionen (z. B. Windows XP oder Windows 2000) funktioniert, sollten Sie andere APIs als WMI verwenden.


Edit:(Auf Kommentar antworten) Ja, können Sie eine verschachtelte ASSOCIATORS OF Abfrage hinzufügen, um die Win32_PhysicalMedia Instanzen zu erhalten entsprechend den Win32_DiskDrive Instanzen; so etwas wie dieses:

... 
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 

Sie haben nicht gesagt, welche Sprache Sie verwenden - ich in Powershell erraten oder C# kann das Ganze mehr elegant getan werden, aber VBScript ist ziemlich ausführlich.

+0

Vielen Dank! Win32_PhysicalMedia ist, soweit ich weiß, vor Windows Vista verfügbar. Muss ich diese drei WMI-Objekte über Assoziatoren "verbinden", um Kompatibilität mit Windows XP zu erreichen? – j00hi

+0

Du hast mir wirklich sehr geholfen! Vielen Dank! Ich musste es in C++ schreiben, aber das Vorgehen ist das gleiche. Ich werde meinen C++ Code veröffentlichen, vielleicht könnte es für jemanden nützlich sein. – j00hi

9

Hier ist der C++ - Code, der das Gleiche tut wie der von Helen veröffentlichte VBScript-Code.

// 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 
+0

Die coole Sache ist, dass dieser Code bis mindestens Windows XP kompatibel ist. Ich habe diesen Code erfolgreich auf Win7 64bit, Win7 32bit und WinXP getestet. – j00hi

Verwandte Themen