Search code examples
powershellwmi

Pass array of CimInstance to CimMethod


I am working with WMI API through Cim cmdlets. The problem is that I can't figure out how to pass wmi object to wmi method that accepts array of wmi objects.

Here are method parameters definition:

Name                                            CimType Qualifiers
----                                            ------- ----------
Path                                             String {ID, in}
Permissions                               InstanceArray {EmbeddedInstance, ID, in}
ResetChildren                                   Boolean {ID, in}

Path and ResetChildren are simple parameters. They accepts simple values like "/path" and $true respectively. But I have troubles with Permissions parameter.

Here is my code

#Acquiring object that I want to pass to method
$group = Get-CimInstance -Namespace "root\VisualSVN" -ClassName VisualSVN_Group -Filter "Name='Readers'"

#Acquiring object which method will be called
$repositories = Get-CimInstance -Namespace "root\VisualSVN" -ClassName VisualSVN_Repository

#Preparing method arguments
$args = @{
    Path = "/";
    Permissions = @($group[0]); #Trouble here
    ResetChildren = $true
}

#Invoking method with arguments
Invoke-CimMethod -InputObject ($repositories[0]) -MethodName SetSecurity -Arguments $args

Execution of this code will result in error:

Invoke-CimMethod : Unable to cast object of type 'Microsoft.Management.Infrastructure.CimInstance' to type 'M
icrosoft.Management.Infrastructure.Native.InstanceHandle'.
Parameter name: value
At C:\somepath\script1.ps1:11 char:1
+ Invoke-CimMethod -InputObject ($repositories[0]) -MethodName SetSecurity -Argume ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-CimMethod], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.Management.Infrastructure.CimCmdlets.Invoke
   CimMethodCommand

If you change code

Permissions = @($group[0]); #Trouble here

To code

Permissions = $group; #Trouble here

Then error message will also change:

Invoke-CimMethod : Unable to cast object of type 'Microsoft.Management.Infrastructure.Native.InstanceHandle'
to type 'System.Collections.IList'.
Parameter name: value
At C:\somepath\script1.ps1:11 char:1
+ Invoke-CimMethod -InputObject ($repositories[0]) -MethodName SetSecurity -Argume ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-CimMethod], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.Management.Infrastructure.CimCmdlets.Invoke
   CimMethodCommand

Any ideas how to pass $group to method properly?


Solution

  • I had exactly same problem with VisualSVN_Repository::SetSecurity method.

    When working with CIM method arguments, you must cast ANY array arguments to [CimInstance[]].

    For example, this worked for me:

    $Everyone = Get-CimInstance -Namespace root/VisualSVN -ClassName VisualSVN_Everyone
    # Grant Everyone a Read/Write access:
    $AccessRule = New-CimInstance -Namespace root/VisualSVN -ClassName VisualSVN_PermissionEntry -ClientOnly -Property @{ Account = $Everyone; AccessLevel = [UInt32]2 }
    $SvnRepo = Get-CimInstance -Namespace root/VisualSVN -ClassName VisualSVN_Repository -Filter "Name='MY_REPOSITORY_NAME'"
    
    Invoke-CimMethod -InputObject $SvnRepo -MethodName SetSecurity -Arguments @{ 
        Path = '/';
        Permissions = [CimInstance[]]$AccessRule;
        ResetChildren = $true
    } | Out-Null
    

    You must cast array argument to [CimInstance[]] even when it is just a single item.

    P.S.: Be careful with Ref array arguments too: you must first cast it to [CimInstance[]] and then to [ref[]]. For example, when calling VisualSVN_Group::Create method:

    [CimInstance[]] $SvnUsers = [CimInstance[]]($ArrayOf_VisualSVN_User_Objects)
    
    Invoke-CimMethod -ClassName VisualSVN_Group -Namespace root/VisualSVN -MethodName Create -Arguments @{
        Members = [ref[]]$SvnUsers;
        Name = 'MY_NEW_GROUP_NAME'
    } | Out-Null
    

    See also: Tip#5: Passing ref and embedded instances on PowerShell Blog.