DComSessionOptions and CimSessionOptions in Workflow

rated by 0 users
This post has 2 Replies | 2 Followers

Top 200 Contributor
Posts 19
stevlars Posted: 03-07-2013 11:30 AM

This question is a cross between WMI (via CIM) and Workflow.  I hope I picked a reasonable forum.

My code looks for a specific service on a set of machines.  I am able to get this to work using Get-WMIObject in a workflow as in the following:

workflow w1 {

    param([string[]]$computerName)

    foreach  -parallel($computer in $computerName) {

        Get-WmiObject -PSComputerName $computer -Class Win32_Service -filter "Name = 'Dhcp'" | Select -property Name, @{n="Computer";e={"$($_.SystemName)"}}

    }

}

$computerList = @("Computer1"," Computer2"," Computer3")

W1 -computerName $computerList | Select-Object Name, Computer

I wanted to try using the CIM activities also and see if there is any performance difference.  (I was suprised to see an indication for a small number of machines that the workflow seemed to perform faster than letting Get-WmiObject use its own job capabilities by passing in multiple computers.)  I do need to fall back to DCOM being PowerShell is not on all the machines.  This is what I came up with:

$computerList = @("Computer1"," Computer2"," Computer3")

$opt = New-CimSessionOption -Protocol DCOM

foreach ($computer in $computerList) {

    $sd = New-CimSession -ComputerName $computer -SessionOption $opt

    Get-CimInstance -CimSession $sd -ClassName Win32_Service -filter "Name = 'Dhcp'" | Select -property Name, @{n="Computer";e={"$($_.SystemName)"}}

}

That works fine also and uses the CIM cmdlets.  Then I run into a problem making this a workflow.  The following is my attempt:

workflow w2 {

    param([string[]]$computerName)

    $opt = New-CimSessionOption -Protocol DCOM

    foreach ($computer in $computerName) {

        $sd = New-CimSession -PSComputerName $computer -SessionOption $opt

        Get-CimInstance -CimSession $sd -ClassName Win32_Service -filter "Name = 'Dhcp'" | Select -property Name, @{n="Computer";e={"$($_.SystemName)"}}

    }

}

$computerList = @("Computer1"," Computer2"," Computer3")

w2 -computerName $computerList | Select-Object Name, Computer

That fails with:

Cannot convert value "Microsoft.Management.Infrastructure.Options.DComSessionOptions" to type "Microsoft.Management.Infrastructure.Options.CimSessionOptions". Error: "Cannot convert the "Microsoft.Management.Infrastructure.Options.DComSessionOptions" value of type "Deserialized.Microsoft.Management.Infrastructure.Options.DComSessionOptions" to type "Microsoft.Management.Infrastructure.Options.CimSessionOptions"."

    + CategoryInfo          : InvalidArgument: (:) [], ParentContainsErrorRecordException

    + FullyQualifiedErrorId : InvalidCastConstructorException

    + PSComputerName        : [localhost]

There is nothing in the help for New-CimSessionOption cmdlet that says anything about returning different types--hopefully the New-CimSessionOption activity would be the same.  That may be the problem though.  I looked at the types in MSDN and those two types do have a different set of properties (DcomSessionOptions has more).

Why would PowerShell need to convert the options when running in a workflow when it does not need to (or have a problem doing so) when not in a workflow?

 Steve

Top 25 Contributor
Posts 526
Microsoft MVP
Top Contributor

As you are aware, this is not the good candidate for a workflow, but it's an interesting test. (I'm surprised that workflow runs faster than Get-WmiObject.)

The error message is long and hard to read, so you've missed the important part in it--"Deserialized."

Cannot convert value "Microsoft.Management.Infrastructure.Options.DComSessionOptions" to type "Microsoft.Management.Infrastructure.Options.CimSessionOptions". Error: "Cannot convert the "Microsoft.Management.Infrastructure.Options.DComSessionOptions" value of type "Deserialized.Microsoft.Management.Infrastructure.Options.DComSessionOptions" to type "Microsoft.Management.Infrastructure.Options.CimSessionOptions"."

What you need to do is to wrap your "CIM code" in inlinescript block. That way all commands will be treated as one entity. Your WMI workflow worked only because everything was a one-liner and deserialization didn't remove the properties that Select-Object expected. Run the following code and look at the returned object:

workflow testwf {

get-wmiobject -Class win32_bios| get-member

}

testwf

 

Top 200 Contributor
Posts 19

Thanks Aleksander.

I did miss the Deserialized part.

I knew about using inlinescript and the CIM test is working with that.

I will see what I learn about performance with a larger set of computers when I get a chance.  A set of three computers is hardly convincing for me either way. 

Page 1 of 1 (3 items) | RSS
Copyright 2012 PowerShell.com. All rights reserved.