Invoking WMI methods with Invoke-WmiMethod - by Shay Levi

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 624263 Comments
Status Closed Workarounds
Type Bug Repros 3
Opened 11/24/2010 4:26:23 AM
Access Restriction Public


In PowerShell V1 we invoked class methods with the following:

$d = Get-WmiObject -Class Win32_Volume -Filter "DriveLetter='D:'"

To verify the order of arguments passed to the method we check the OverloadDefinitions for the Format method :

System.Management.ManagementBaseObject Format(
	System.String FileSystem, 
	System.Boolean QuickFormat, 
	System.UInt32 ClusterSize, 
	System.String Label, 
	System.Boolean EnableCompression,
	System.UInt32 Version

In PowerShell V2 we have a new way to invoke methods with the Invoke-WmiMethod cmdlet. 
If we use the same approach of passing arguments in the specified order of OverloadDefinitions the cmdlet fails and generates an error.

PS > Get-WmiObject Win32_Volume -Filter "DriveLetter='D:'" | Invoke-WmiMethod -Name Format -ArgumentList 'NTFS',$true,4096,'',$null,$null

Invoke-WmiMethod : Input string was not in a correct format.

The help of the ArgumentList parameter states that - "The value of this parameter must be an array of objects and they must appear in the order required by the called method."
The explanation doesn't specify what is the correct order required by the called method. 
It seems that Invoke-WmiMethod is using the order of arguments as specified in  the GetMethodParameters method (different order): 

PS > ([wmiclass]"win32_volume").GetMethodParameters('Format')

__GENUS           : 2
__CLASS           : __PARAMETERS
__RELPATH         :
__DERIVATION      : {}
__SERVER          :
__NAMESPACE       :
__PATH            :
ClusterSize       : 0
EnableCompression : False
FileSystem        : NTFS
Label             :
QuickFormat       : False
Version           : 0

Moreover, even if we pass the arguments in the above order the cmdlet still fails:

Get-WmiObject Win32_Volume -Filter "DriveLetter='D:'" | Invoke-WmiMethod -Name Format -ArgumentList 4096,$false,'NTFS','',$true,$null

Invoke-WmiMethod : Unable to cast object of type 'System.Management.Automation.PSObject' to type 'System.IConvertible'.

The command works only if we explicitly cast ArgumentsList to an array (i.e '@()'):

Get-WmiObject Win32_Volume -Filter "DriveLetter='D:'" | Invoke-WmiMethod -Name Format -ArgumentList @(4096,$false,'NTFS','',$true,$null)

__GENUS          : 2
__CLASS          : __PARAMETERS
__RELPATH        :
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
ReturnValue      : 0

Sign in to post a comment.
Posted by Romfont on 7/31/2012 at 6:16 PM
I can confirm that something is wonky with argument order in Powershell calling WMI method. I have a decoupled provider in C#, code is like this:

    static public int Foo(string a, string b, string c, string d)
        Console.WriteLine("A: " + a);
        Console.WriteLine("B: " + b);
        Console.WriteLine("C: " + c);
        Console.WriteLine("D: " + d);

I call it like so:

invoke-wmimethod -namespace [...] -class [...] -name Foo -argumentlist "a", "b", "c", "d"

which prints output as expected:

A: a
B: b
C: c
D: d

However, if I change the signature to the following:

    static public int Foo(string z, string b, string c, string d)
        Console.WriteLine("A: " + z);
        // etc ...

... and call it in the same way as before, I get the output:

A: d
B: a
C: b
D: c

Which is obviously the wrong order. Maybe the arguments are put into a hashmap somewhere and hashed by name?

My provider is written in C# and uses the .net framework version 4.0. I've confirmed this behavrior on two machines, one is Win7:

    CurrentVersion    REG_SZ    6.1
    CurrentBuild    REG_SZ    7601

The other is Win8:

    CurrentVersion    REG_SZ    6.2
    CurrentBuild    REG_SZ    8400

Powershell version is 3.0 (-1,-1)
Posted by Jade S Gardiner on 7/6/2012 at 1:05 PM
The Create method of Win32_DFSNode also has this problem.

When called as ([wmiclass]"Win32_DFSNode").Create(...) it expects the parameter order DFSEntryPath, ServerName, ShareName, Description, as per the documentation.

When called with Invoke-WMIMethod it expects the optional Description parameter first!

Invoke-WMIMethod appears to completely ignore the order declared in the MOF file, and instead appears to use arguments in the order it receives them from WMI, which happens to be alphabetical! This is clearly not the intended behaviour of Invoke-WMIMethod, nor is it the behaviour claimed in the documentation.
Posted by Thomas Lee on 9/6/2011 at 6:36 AM
As I understood it, the order in the method call and the order for the Invoke-WMI Method's -argumentlist should be the same.

Having said that, his fails:
invoke-wmimethod -class Win32_Share -name Create -ArgumentList $null,'foo',20,'foo',$null,'c:\foo',0

Whereas, this works:
invoke-wmimethod -class Win32_Share -name Create -ArgumentList ($null,'foo',20,'foo',$null,'c:\foo',0)