Question:
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:
1 2 3 4 5 6 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#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:
1 2 3 4 5 6 7 8 9 10 |
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
1 2 |
Permissions = @($group[0]); #Trouble here |
To code
1 2 |
Permissions = $group; #Trouble here |
Then error message will also change:
1 2 3 4 5 6 7 8 9 10 |
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?
Answer:
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:
1 2 3 4 5 6 7 8 9 10 11 |
$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:
1 2 3 4 5 6 7 |
[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.