WMI:通过另一个程序运行shell命令时出现“无效类”错误

4

我正在尝试获取PCoIP统计信息,这些信息可以通过WMI获取。我使用以下命令进行WMIC:

 wmic path Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics

或者使用PowerShell。
powershell Get-WmiObject -namespace "root\cimv2" -computername computer01 -class Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics

然而,当我尝试通过另一个进程来运行这两个命令时(在本例中是Python),并将stdout进行管道传输时,会出现以下类无效错误。

 Get-WmiObject : Invalid class
At line:1 char:14
+ Get-WmiObject <<<  -namespace root\cimv2 -computername computer01 -class
 Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

如果有帮助的话,通过命令提示符执行powershell命令的输出结果为:
__GENUS                   : 2
__CLASS                   : Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkS
                            tatistics
__SUPERCLASS              : Win32_PerfRawData
__DYNASTY                 : CIM_StatisticalInformation
__RELPATH                 : Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkS
                            tatistics.Name="PCoIP Session"
__PROPERTY_COUNT          : 19
__DERIVATION              : {Win32_PerfRawData, Win32_Perf, CIM_StatisticalInfo
                            rmation}
__SERVER                  : DEMO-VSGA-WS01
__NAMESPACE               : rootcimv2
__PATH                    : \DEMO-VSGA-WS01rootcimv2:Win32_PerfRawData_Terad
                            iciPerf_PCoIPSessionNetworkStatistics.Name="PCoIP S
                            ession"
Caption                   :
Description               :
Frequency_Object          : 0
Frequency_PerfTime        : 10000000
Frequency_Sys100NS        : 10000000
Name                      : PCoIP Session
RoundTripLatencyms        : 284
RXBWkbitPersec            : 22034
RXBWPeakkbitPersec        : 4
RXPacketLossPercent       : 112
RXPacketLossPercent_Base  : 28805
Timestamp_Object          : 0
Timestamp_PerfTime        : 299873128867
Timestamp_Sys100NS        : 130641888164850000
TXBWActiveLimitkbitPersec : 1832
TXBWkbitPersec            : 75615
TXBWLimitkbitPersec       : 90000
TXPacketLossPercent       : 7
TXPacketLossPercent_Base  : 30942

我也尝试使用Python模块WMI。
hostname = os.getenv('COMPUTERNAME', '')
c = wmi.WMI (hostname, namespace="root\\cimv2")
print c.Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics

我遇到了以下错误:
print c.Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics
  File "c:\users\ramesh~1\appdata\local\temp\easy_install-tlfipc\WMI-1.4.9-py2.7
-win32.egg.tmp\wmi.py", line 1147, in __getattr__
  File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 522, in
__getattr__
    raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: winmgmts://computer01/root/cimv2.Win32_PerfRawData_TeradiciP
erf_PCoIPSessionNetworkStatistics

这是否与调用者的模拟和身份验证级别有关?
更新
我将PowerShell命令移动到批处理文件中,当我通过CMD运行批处理文件时,它再次正常工作。
当通过Python的Popen运行时,显示相同的错误。如果有帮助,我正在使用Python代码。
p = subprocess.Popen ('bat.bat',stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print p.stdout.read()

我试图列出该命名空间下的类,当通过CMD调用批处理文件时,该类被列出,但是当使用Popen时,Teradici的类都无法使用。bat.bat文件中的命令行为:

powershell Get-WmiObject -namespace "root\cimv2" -computername computer01 -list

所有这些都在VMWare VDI(虚拟桌面基础架构)上运行,是否可能有任何策略限制?

这似乎表明存在解析问题:-namespace rootcimv2 - mjolinor
@mjolinor 我没有意识到转义字符的问题,我修改了程序,但是仍然出现“无效类”的错误。 - user1064504
WMI提供程序只注册在32位或64位中的一种可能性有吗?运行32位和64位的PowerShell,并运行Get-WmiObject -List Win32_PerfRawData_Teradici* - Bacon Bits
@BaconBits 尝试在powershell(x86)和powershell(x64)中使用相同的get-wmiobject,两者都返回正确的信息。 - user1064504
@BaconBits 请查看更新。 - user1064504
1个回答

3
经过一段时间的故障排除,问题似乎是由于32位程序无法访问所需的类,尽管我通过PowerShell(x64和x86)尝试时得到了正确的响应。
否则,64位WMI提供程序可以通过32位程序访问,反之亦然,只需正确设置__ProviderArchitecture和__RequiredArchitecture WMI上下文标志即可。
以下是一个Python示例:
import win32com.client
import wmi
import os

objCtx = win32com.client.Dispatch("WbemScripting.SWbemNamedValueSet")
if self.is64Windows():
    objCtx.Add ("__ProviderArchitecture",  64)
else:
    objCtx.Add ("__ProviderArchitecture",  32)
objCtx.Add ("__RequiredArchitecture", True)
server = wmi.connect_server (server = "localhost", namespace="root\\cimv2", named_value_set=objCtx)
connection = wmi.WMI (wmi = server)

关于上下文标志的更多信息可以在 MSDN 上找到。 此外,对于 WMI 调试和故障排除,您还可以参考以下链接:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接