SCO: Run .NET Script Workarounds for PowerShell

Greetings and Felicitations, readers! This week’s blog post is on the subject of System Center Orchestrator and the very useful, yet sometimes fickle, Run .NET Script activity.

 

As many users are already aware, the Run .NET Script activity can be used to run PowerShell scripts directly within a runbook, processing or generating data and publishing it back out to the databus. This grants an extreme amount of flexibility to any workflow – in fact, because of the greater degree of power and flexibility afforded by PowerShell versus many of the Integration Pack activities, I often find myself creating runbooks that are primarily assembled with little more than linked PowerShell scripts, bypassing the Integration Pack activities altogether.

 

Still, the Run .NET Script activity is not without its limitations. One significant limitation is that the PowerShell session used by the Run .NET Script activity is stuck in PowerShell version 2.0, not supporting many of the current PowerShell capabilities and not able to load some PowerShell modules (such as that of SCVMM). As a result, scripts sometimes need to be written carefully in order to ensure they’ll function, or certain workarounds need to be put into place.

 

Here are two workarounds I use frequently when leveraging more advanced PowerShell scripts in Orchestrator:

 

Workaround #1

 

This first workaround involves opening a separate PowerShell session on the Runbook server, allowing use of the default version of PowerShell which is installed. This approach can be used to run specific commands, a series of commands, or an entire script in a separate session, and allows for data to be passed into the separate session and returned at the end. It functions by wrapping the desired script within a script block invoked simply by calling PowerShell:

 

The sample above displays more complexity than is required, but illustrates how the technique can be used. Data can be passed into the separate session by creating a Param() block inside the script block, defining the number and type of inputs, and following the script block with the -Args parameter, followed by the values or variables to be passed in. Output can be captured by assigning the whole section to a variable and returning the desired data from within the script block. If no data needs to be passed back, all that is needed is to wrap the desired script in Powershell { ## Work } and call it a day.

 

This first workaround is the “quick and dirty” method – easy to implement, but limited in what it can do. It works fantastic, though, when the command or script can be ran locally and with the runbook service account’s credentials. When separate credentials or a separate server are needed, I leverage this second workaround.

 

Workaround #2

 

This second workaround is much more powerful, able to leverage a separate PowerShell session either local or remote, able to leverage separate credentials, and able to leverage variables from the host session without having to add a parameter block. This approach creates a new PSSession on the target computer and again leverages a script block to invoke commands within the separate section. This approach does require that PSRemoting is configured correctly and that the account being used has access to connect to the target computer, whether local or remote. Make certain to review the about_Remote_Requirements article on Technet to confirm the necessary server configuration is in place before usage, otherwise the about_Remote_Troubleshooting article will be your friend. Here’s a template for this technique:

 

As with the first sample, this displays more complexity than is absolutely needed, but illustrates how the technique can be used, including leveraging Try/Catch/Finally for error handling, both within the remote session and the host session. Additionally, a username and password can be passed into the script either from the databus or from a variable; these will be used to create a PSCredential object which will be used to open the separate session. If you’d like to call variables from the host session in the remote session, rather than requiring a Param() block to be used, the variables simply need to be prefaced with “$Using:” to inform PowerShell to pass them through. For example, to use a variable from the local scope called “OrganizationalUnit”, when referenced in the script block, it would need to be written as $Using:OrganizationalUnit and PowerShell would take care of the rest.

 

As part of the sample’s error handling, throw is used within the Catch{} script blocks to throw an exception in case of failure. In Orchestrator, this will have the result of causing the Run .NET Script activity to complete with an Error status and the error message from the script to be added to the activity’s Error Summary Text output. This can grant considerable insight into the cause of script failures via Orchestrator.

 

Closing Thoughts

 

Both of these workarounds are frequently used within my Orchestrator scripting. However, the techniques have a wide range of applications elsewhere as well – Workaround #1 is also very useful with custom workflows in Service Manager (like this one), and #2 is a staple for running PowerShell scripts against multiple servers. Hopefully these tricks can come in handy for you as well!

 

As always, please feel free to leave any questions or comments in the comment box below. Thanks for reading!

By |2016-06-09T08:20:07+00:00January 28th, 2015|Orchestrator|0 Comments

About the Author:

Solutions Architect / Team Lead – Model Technology Solutions Gabriel specializes in SCOM, SCSM, Orchestrator, and PowerShell, along with experience in several Azure technologies and other server roles. Gabriel has spoken at several regional conferences and user group meetings about leveraging Microsoft’s datacenter and automation technologies to solve specific problems. Gabriel’s attention to detail and relentless pursuit of perfection may one day make his brain explode from information overload. Hopefully they will have a cure before then.

Model Technology

Let us help you get your end point and data center strategy on cruise control!  Ask about our Calibration Assessment.

CONTACT US

  • 12125 Woodcrest Executive Drive, Ste. 204 Creve Coeur, MO 63141
  • (314) 254-4138
  • sales@model-technology.com

RECENT TWEETS