Get-WMIObject \ Get-CimInstance实际做什么?

时间:2020-05-14 02:54:43

标签: powershell visual-c++ com wmi get-wmiobject

我正在开发一个新的WMI实例提供程序,但遇到了一些麻烦。我可以使用regsvr32.exe成功注册我的提供商。 regsvr32应用程序调用我的DllRegisterServer的实现,并创建以下注册表项和值:

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}                : (default)      = "WMI Provider"
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\InprocServer32 : (default)      = "C:\MyWmiProvider.dll"
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\InprocServer32 : ThreadingModel = Neutral
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\Version        : (default)      = 1.0.0

(其中{00000001-0000-0000-0000-00000000000F}只是测试类ID(CLSID))

我还能够通过使用以下命令成功添加在 M 岁的 O 对象 F ormat(MOF)文件中定义的WMI类定义mofcomp.exe。通过运行以下命令,我可以验证我的定义是否存在于WMI存储库中:

Get-CimClass -Namespace "root/MyNamespace" | Where-Object CimClassName -like "MyClass_*"

以下是我的MOF文件的示例:

#pragma namespace("\\\\.\\root\\MyNamespace")
#pragma autorecover

instance of __Win32Provider as $P
{
    Name = "MyWmiProvider";
    ClsId = "{00000001-0000-0000-0000-00000000000F}";
};

instance of __InstanceProviderRegistration
{
    Provider = $P;
    SupportsGet = FALSE;
    SupportsPut = FALSE;
    SupportsDelete = FALSE;
    SupportsEnumeration = TRUE;
};

[dynamic, provider("MyWmiProvider")]
class MyClass_ExampleName
{
    [key]
    uint14 Id;

    [PropertyContext("Name")]
    String Name;
};

现在,如果我运行以下命令:

Get-CimInstance -Namespace "root/MyNamespace" -Class "MyClass_ExampleName"

这会在PowerShell中产生以下错误:

Get-CimInstance : Provider load failure  
At line:1 char:1
+ Get-CimInstance -Namespace "root/MyNamespace" -Class "MyClass_ExampleName"  
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    + CategoryInfo          : NotSpecified: (root/Surface:Device_Status:String) [Get-CimInstance], CimException  
    + FullyQualifiedErrorId : HRESULT 0x80041013,Microsoft.Management.Infrastructure.CimCmdlets.GetCimInstanceCommand

同样,执行此命令时会生成三(3)个事件查看器日志:

  1. MyWmiProvider提供程序以结果代码0x80041013开始。 HostProcess = wmiprvse.exe; ProcessID = 2144; ProviderPath = C:\ MyWmiProvider.dll

  2. Id = {FB6B3CF7-293E-0002-9316-73FB3E29D601}; ClientMachine = RTR-USERNAME;用户= MYDOMAIN \用户名; ClientProcessId = 19416;组件=未知;操作=启动IWbemServices :: CreateInstanceEnum-root \ MyNamespace:MyClass_ExampleName; ResultCode = 0x80041013;可能的原因=未知

  3. MyWmiProvider提供程序以结果代码0x80041013开始。 HostProcess = wmiprvse.exe; ProcessID = 24636; ProviderPath = C:\ MyWmiProvider.dll

(表明WMI确实找到了DLL)

如果我尝试调用Get-WMIObject,除了第二个事件查看器日志说“ Operation” “ Start IWbemServices :: ExecQuery-root \ MyNamespace之外,我会得到类似的结果: MyClass_ExampleName”

Get-WMIObjectGet-CimInstance在后​​台做什么?

我已经查找了Get-WMIObject [here]的源代码,尽管仅用了6行,但是查找方面类和函数调用并没有产生详细的细节。我的DLL接口仅包括四(4)个导出函数:DllGetClassObject()DllCanUnloadNow()DllRegisterServer()DllUnregisterServer()。我以为Get-WMIObjectGet-CimInstance都首先调用DllGetClassObject()以获得WMI类工厂,但是如果我放置一个函数调用以将字符串保存到{ {3}},我在调用这些PowerShell命令时注意到没有创建临时文件。

通过在DllGetClassObject()之后创建一个新项目,我变得更加具体,这样我就可以调用以下内容:

DEFINE_GUID(InstanceProviderClassID, 0x00000001, 0x00000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F);

IWbemServices * pLoc = NULL;
CoCreateInstance(InstanceProviderClassID, NULL, CLSCTX_INPROC_SERVER, IID_IWbemServices, (LPVOID *)&pLoc);

在这种情况下,对this answer的呼叫成功。我什至还注意到临时日志文件已创建,表明实际上CoCreateInstance()已被调用!

即使我采用自己拥有的工作实例提供程序,并将相同的打印语句(或类似的调用以创建注册表项/值)放入其DllGetClassObject()函数中,也不会保存任何内容来表明这一点调用这些PowerShell命令时会调用该函数。

1。我在这里想念什么?
2.为什么在同时执行Get-WMIObjectGet-CimInstance时从未调用DllGetClassObject()函数?
3.为什么我能够成功执行DllGetClassObject(),说明我的提供程序编码正确,但是在执行其中一个PowerShell命令时却出现了“提供商加载失败”
< / p>

(附带说明:为了使事情变得容易,我在WBEM_E_NOT_SUPPORTED上标记了CoCreateInstance()。在工作实例提供程序中完成此操作后,我仍然看不到“ provider加载失败” ,而是“不支持。”

0 个答案:

没有答案
相关问题