Comment se joindre à une Requête WMI (WQL)
Question
Je veux obtenir le numéro de série de l'amorçage du disque dur via une requête WQL.
La partition boot qui peut être récupéré à l'aide de la requête suivante:
SELECT * FROM Win32_DiskPartition where BootPartition=True
Le numéro de série est dans Win32_DiskDrive:
SELECT DeviceID, SerialNumber FROM Win32_DiskDrive
Win32_DiskDriveToDiskPartition
a la cartographie de Win32_DiskDrive
pour Win32_DiskPartition
.Ils sont mappés Win32_DiskDrive.DeviceID
pour Win32_DiskPartition.DeviceID
dans Win32_DiskDriveToDiskPartition
Comment puis-je construire une requête WQL que les jointures internes Win32_DiskPartition
et Win32_DiskDrive
?Dois-je utiliser Associators ou est-ce de travailler avec INNER JOIN?
La solution
WQL ne prend pas en charge le JOIN
la clause.Vous devez utiliser le ASSOCIATORS OF
déclaration comme vous l'avez deviné.Voici un exemple dans 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
Notez, cependant, que l' Win32_DiskDrive.SerialNumber
la propriété n'est pas disponible avant Windows Vista.Donc, si vous voulez que votre code fonctionne sur les versions antérieures de Windows (par ex.Windows XP ou Windows 2000), vous devez envisager d'utiliser des Api autres que WMI.
Edit: (réponse à un commentaire) Oui, vous pouvez ajouter un imbriquée ASSOCIATORS OF
requête pour obtenir l' Win32_PhysicalMedia
les instances correspondant à la Win32_DiskDrive
instances;quelque chose comme ceci:
...
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
Vous n'avez pas dit ce que la langue que vous utilisez, je suppose que dans PowerShell ou C#, le tout peut être fait de manière plus élégante, mais VBScript est assez verbeux.
Autres conseils
Voici le code C++ qui fait la même chose que le code VBScript posté par Helen.
// 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