Windows PowerShell: Common parameters and runtime variables

Each month this year, Don Jones will present an installment in a 12-part tutorial on Windows PowerShell Workflow. We encourage you to read through the series in order, beginning with the January 2013 column.

Don Jones

One of the neat things about a workflow is you get a ton of built-in functionality. For example, every workflow you write natively knows how to talk to remote computers via Windows PowerShell remoting (Windows Remote Management, known as WinRM).

That means you can write every workflow to run against the local computer, and you can remote the entire thing. Common workflow parameters and variables let you access these native “shortcut” features.

Common workflow parameters

These are all documented in the about_WorkflowCommonParameters help file, although you need to manually import the PSWorkflow module in Windows PowerShell 3.0 in order for that help file to be visible. Here’s a look at some of the more common ones:

  • -AsJob forces the workflow to run as a background job. The related -JobName parameter lets you apply a custom name to the job.
  • -PSAuthentication lets you specify an authentication mechanism, such as Kerberos or Credential Security Support Provider (CredSSP), for remote connections. CredSSP is useful when the workflow needs to access non-local resources that require an additional network “hop.”
  • -PSComputerName lets you specify one or more computer names upon which you plan to run the workflow. For example, -PSComputerName (Get-ADComputer -filter * | Select -Expand Name) would run the workflow on all domain computers. You should be careful with this one.
  • -PSConnectionRetryCount specifies the number of times the workflow will attempt to connect to each remote computer, and -PSConnectionRetryIntervalSec is the number of seconds to wait between attempts.
  • -PSCredential lets you specify an alternate credential for remote connections.
  • -PSParameterCollection lets you specify a hashtable of workflow common parameters. This one is tricky. You can specify a comma-separated list of hashtables, with each hashtable connecting to one or more computers. For example, this specifies a different connection retry count for computers ONE and TWO: -

PSParameterCollection, @{PSComputerName='ONE';PSConnectionRetryCount=10},@{PSComputerName='TWO';PSConnectionRetryCount=20}

  • PSPort and -PSUseSSL let you specify alternate ports and optionally enable SSL (assuming the remote machines have a valid SSL certificate and WinRM listener configured) for the connection.

Remember, all workflows get these options. You don’t have to write any code to make them work. And they’re free, which is awesome.

Automatic workflow variables

All normal Windows PowerShell automatic variables, such as $Args, $Error, $MyInvocation, $PSBoundParameters and $PsCmdlet, are available within a workflow. Workflows add much more on top of what Windows PowerShell provides:

  • $PSParentActivityID provides a unique identifier for the current scope and for all child scopes. This lets you uniquely identify each instance of a workflow, such as when you want to log information to a central file.
  • $PSWorkflowRoot contains the root path of a workflow.
  • $WorkflowInstanceID is the unique identifier for the workflow instance.

An entire set of variables reflects the contents of the common workflow parameters described earlier. For example, $PSComputerName contains the -PSComputerName parameter’s value. You can also use $ParentJobName and $JobName to access job information. If -PSComputerName contains multiple values, then each computer running the workflow will see only its own name in $PSComputerName. Check this complete list of variables for additional reference.

Variable rules

Remember that variables in a workflow work a bit differently. For example, you can’t assign the results of a subexpression to a variable. Instead of:

$x = $(Get-Service)

You’d just run:

$x = Get-Service

Also, you can’t assign a variable value to another variable in the same statement:

$a = $b = 23

You’d have to do that as two separate operations. Also, you can’t put an object in a variable and change that object’s properties:

$obj = New-PSSessionOption $obj.SkipCACheck = $true

Your own parameters and variables

Your workflows can of course define their own input parameters in a Param block. These are exposed within the workflow as variables. For example, defining -MyParam gives you a $MyParam variable inside the workflow. Just don’t add the common workflow parameters. Those are magically added by Windows PowerShell when the workflow runs.

Activity common parameters

Here’s a confusing bit—every command you run in a workflow, or every block of commands you run in an InlineScript{} block, is considered an activity. Windows PowerShell adds common parameters to those activities as well, including -PSComputerName. Because these activities look like normal cmdlets, this can be confusing. For example:

Get-Process –PSComputerName ONE,TWO,THREE

The normal Get-Process cmdlet has a -ComputerName parameter, but not a -PSComputerName parameter. The latter is valid only within a workflow, where Get-Process technically isn’t a cmdlet—it’s a workflow activity. An InlineScript{} block supports these parameters:

InlineScript { Get-Process } –PSComputerName ONE,TWO,THREE

The commands inside the InlineScript{} are just cmdlets. They don’t get the activity common parameters. Finally, and just to make things more confusing, any command that doesn’t have an equivalent workflow activity will be implicitly wrapped in an InlineScript{}, but can’t use the common activity parameters. For example:

Get-WindowsFeature

That’s a command, not a workflow activity. There’s no equivalent activity available. Not that you’d know that, because there’s no way to tell. But you can’t add -PSComputerName to it. This is where workflow gets annoying, because there’s no way to easily tell what is an activity and what isn’t. So you won’t always know, except to try it and have it either succeed or fail.

See how this gets tricky?

This is where working with workflows starts to become difficult. You’ve got all these extra bits happening under the hood. While most are helpful, they’re not consistently implemented. You end up with a lot of trial and error.

Just remember, workflow is a different world. Windows PowerShell is just providing a gateway to it. You can’t expect full consistency with the normal Windows PowerShell environment.

Don Jones

Don Jones is a Windows PowerShell MVP Award recipient, and a contributing editor to TechNet Magazine. He has coauthored four books about Windows PowerShell version 3.0, including free ones on Windows PowerShell remoting and creating HTML reports in Windows PowerShell. Find them all at PowerShellBooks.com, or ask Jones questions in the discussion forums at PowerShell.org.