powershellwmivmwarewmi-queryvdi

WMI:Getting Invalid Class Error when running shell command through another program


I am trying to get PCoIP Statistics which are available through WMI, I use following command for WMIC

 wmic path Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics

or with powershell

powershell Get-WmiObject -namespace "root\cimv2" -computername computer01 -class Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics

However when I tried to run either command forked through another process, in this case it was python, and piping the stdout, I am getting Invalid class error like below.

 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

if it helps, the output of powershell command through command prompt is

__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

I also tried using python module WMI

hostname = os.getenv('COMPUTERNAME', '')
c = wmi.WMI (hostname, namespace="root\\cimv2")
print c.Win32_PerfRawData_TeradiciPerf_PCoIPSessionNetworkStatistics

I am getting following error

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

Can this be related to impersonation and authentication level of caller?

UPDATE

I moved the powershell command to a bat file, when I run the bat file through CMD, it's again working fine.

When Popen through python, it showing same error. If it helps I am using python code.

p = subprocess.Popen ('bat.bat',stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print p.stdout.read()

I tried listing the classes under the namespace, the class was listed when the bat file was called through CMD, when Popen, none of Teradici's classes were available. The command line in bat.bat is

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

All this is being run on VMWare VDI (Virtual Desktop Infrastructure), can there be any policy restrictions?


Solution

  • After troubleshooting for sometime, The reason seems like, the required class wasn't accessible from 32 bit programs, although when I tried through PowerShell (x64 & x86) I got correct responses.

    Otherwise 64 bit WMI Provider can be accessed through 32 bit Program or vice versa, by correctly setting up __ProviderArchitecture & __RequiredArchitecture WMI Context flags,

    a pythonic example is as follows

    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)
    

    More information about Context Flags can be found on msdn

    Additionally for WMI debugging and troubleshooting you can refer to