a

I’ve finally (What do you mean finally? It’s been around since version 3!) been starting do some work with PowerShell Workflow.

I say finally because in all fairness nothing I have done has actually needed it.   But I’m doing some work on a project that specifically will need parallel processing, and to be honest fiddling with “Start-Job” just won’t cut it.

So I figured I would start with a simple script

function foo([string[]]$testparam)

{
foreach ($Item in $TestParam)
	{
	Write-Host $item
	}
}
foo meow,woof,tweet,cat,dog,funnybird,liver,nih

All this would do is just take an array and write them to the console.  Nothing special.   So really to convert it to a basic (and I mean OH so basic Workflow) was a simple matter of changing FUNCTION to WORKFLOW as the keyword

Workflow foo([string[]]$testparam)

{
foreach ($Item in $TestParam)
	{
	Write-Host $item
	}
}
foo meow,woof,tweet,cat,dog,funnybird,liver,nih

Now to TRULY enable the Power of a Workflow, I’d like to use Parallel processing.  This means it will actually execute a bunch of things Side by Side at nearly the same time.   (I may blog about this later).  You do this by adding in the –parallel parameter to the Foreach statement.  (This is Unique to Workflows)

workflow foo([string[]]$testparam)

{
foreach -parallel ($Item in $TestParam)
    {
    Write-Host $Item
    }
}

foo meow,woof,tweet,cat,dog,funnybird,liver,nih

And at this point I stumbled into the first tripping point in a workflow, non supported Cmdlets and Scenarios for the Workflow engine.

At line:7 char:6
+      Write-Host $item
+      ~~~~~~~~~~~~~~~~
Cannot call the 'Write-Host' command. Other commands from this module have been packaged as workflow activities, but this command was specifically excluded. 
This is likely because the command requires an interactive Windows PowerShell session, or has behavior not suited for workflows. To run this command anyway, 
place it within an inline-script (InlineScript { Write-Host }) where it will be invoked in isolation.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : CommandActivityExcluded

So in reading up you CAN actually use these Cmdlets but you need to wrap them as an “inlinescript” which tells it to wrap up this code and package it off to a PowerShell engine, NOT the Workflow Engine (they are different)

Ok that’s actually pretty easy.   It’s an extra keyboard and works like this with the following simple change to our previous example.

workflow foo([string[]]$testparam)

{
foreach -parallel ($Item in $TestParam)
    {
    inlinescript
        {
        Write-Host $item
        }
    }
}

foo meow,woof,tweet,cat,dog,funnybird,liver,nih

I ran this and no error, but also… No output.   Hmmm…. You would almost think the Object “$item” in the InlineScript block had no value. 

Well it’s true.  It has none.  Think of the InlineScript as similiar to a ScriptBlock.   It’s an isolated entity.   You have to TELL the InlineScript what data it’s going to get to use (or more correctly, what data needs to be exposed to it)

The process is very easy actually.  Each object you would like to use, needs to accessed with a Using like below.  This allows us to “View” $item within the InlineScript

$Using:item

Now you need to assign that value to an object.  Since the InlineScript is isolated, you can actually use the EXACT SAME NAME (which initially DOES look a bit confusing to us ITPros) Here’s the what it looks like

$Item=$Using:Item

And then inserted into our Workflow it looks like this

workflow foo([string[]]$testparam)

{
foreach -parallel ($Item in $TestParam)
    {
    inlinescript
        {
        $item=$Using:Item
        Write-Host $Item
        }
    }
}

foo meow,woof,tweet,cat,dog,funnybird,liver,nih

At this point you have a very basic knowledge of converting a Function to a Workflow.   Converting a script follows pretty the same principals.    Of course we don’t have error checking in this basic example but all of the Principals here are needed.  

Although you can do a pretty decent conversion by uploading to Azure Automation, it’s best to understand the process if you need to directly convert some of your on Premise work into Workflows.

The Advantage to the Workflow scenario is Speed and Efficiency of course. 

Hopefully this little foray into PowerShell Workflows may help you out in your endeavours, if even a little Smile

Cheers!

Sean
The Energized Tech

Advertisements