Search code examples
c#wmi

C# WMI method IsActivated from Win32_Tpm class throws "Invalid method Parameter(s)"


I am trying to run the IsActivated, IsEnabled and IsOwned methods from the Win32_Tpm WMI class in C#.

For testing purposes, I have created a console application with the following code:

        ManagementScope managementScope = new ManagementScope(@"ROOT\CIMV2\Security\MicrosoftTpm");
        ManagementPath managementPath = new ManagementPath("Win32_Tpm");
        ManagementClass managementClass = new ManagementClass(managementScope, managementPath, null);

        managementClass.InvokeMethod("IsActivated", null);

InvokeMethod throws "Invalid method Parameter(s)"

The IsActivated method signature does not mention any input parameter:

uint32 IsActivated(
  [out] boolean IsActivated
);

To confirm this, I ran:

managementClass.GetMethodParameters("IsActivated");

Which returned:

System.Management.ManagementObject.GetMethodParameters returned null

Visual Studio is launched with run as Admin and the app.manifest was configured to require Administrator privileges:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

The methods should definitely work, as showcased in WMI Explorer, but I am struggling to understand what I am doing wrong.


Solution

  • Posting this as an answer as I figured it out in the end and it could come in handy for those encountering the same struggles in the future.

    To be able to run the InvokeMethod method, I needed to define a ManagementObject for the Win32_TPM WMI Instance and not a ManagementClass.

    The key on how to define that instance came from this answer in another thread for a similar question and this C#Corner article.

    To define the instance, I needed 2 things:

    • the path = "ROOT\CIMV2\Security\MicrosoftTpm"
    • the instance name = "Win32_Tpm=@"

    I used the aforementioned WMI Explorer to figure out the instance name.

    ManagementObject managementObject = new ManagementObject(@"ROOT\CIMV2\Security\MicrosoftTpm", "Win32_Tpm=@", null);
    

    Next I stored the output of the InvokeMethod in a ManagementBaseObject:

    ManagementBaseObject OutParams = managementObject.InvokeMethod("IsActivated", null, null);
    

    And finally, you can either parse all the PropertyData:

    foreach(PropertyData propertyData in OutParams.Properties)
    {
       Console.WriteLine($"{propertyData.Name} = {propertyData.Value}");
    }
    

    To produce this output:

    IsActivated = True

    ReturnValue = 0

    Or you can go straight for the PropertyValue:

    Console.WriteLine($"IsActivated = {OutParams.GetPropertyValue("IsActivated")}");
    

    IsActivated = True