Archive for February 2012

Prevent Multiple Invocations of a Runbook   Leave a comment

I’ve moved everything from this blog over to jmattivi.blogspot.com and updated all of the scripts to have straight quotes.  If any don’t work as posted, please let me know!

For further posts please see jmattivi.blogspot.com.

Thanks!

 

There are many occasions where you may want to prevent someone (or schedule) from starting (queuing up) another instance of a Runbook if it’s already running.  There are three ways I’ve found to accomplish this….using counters, the database query activity to look up a running job, and the web service.

While using counters may be the best solution to prevent workflows from running before a prerequisite workflow completes, it’s not the best solution to prevent inadvertently queuing up another runbook instance.

The database query activity can be used in this scenario to query the PolicyInstances table to see if a specific runbook is already running.

The query used would look like this.  Note you need to use the specific Runbook name in the query.

Select POLICIES.Name,POLICYINSTANCES.Status,POLICYINSTANCES.TimeStarted,POLICYINSTANCES.TimeEnded
From POLICYINSTANCES,POLICIES
Where (POLICIES.UniqueID = POLICYINSTANCES.PolicyID) AND TimeEnded is null AND POLICIES.Name = ‘0.1 Runbook B’

Based on the query results, you can use the Link logic to either start the Runbook or send an email that the Runbook is already running and cannot start at this time.

The .NET Script activity can be used in this scenario to query the Jobs collection of the Web Service to see if a specific runbook is already running.

The Powershell script to query the Jobs collection is a little different than I’ve used in prior posts.  Sometimes it’s tedious to look up the RunbookID guid, so this way you can specify the name of the runbook without the guid.  This is accomplished by pointing to the Jobs collection, but also expanding the runbook collection as well to grab it’s associated data.  Then you can use the filter and select statements in the odata query to filter on the name of the runbook.

Here is the URL for the GET request.  Note you need to specify the collection name and property name together for the collection that’s expanded.

$url = “http://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs()?`$expand=Runbook&`$filter=(Status eq ‘Running’) and (Runbook/Name eq ‘0.1 Runbook B’)&`$select=Runbook/Name,Status”

Here is the complete script to query the web service (fields in red would need to be updated per your environment):

#########################################################################################

$user = “domain\username
$pass = ConvertTo-SecureString “password” -AsPlainText -Force
$creds = New-Object System.Management.Automation.PsCredential($user,$pass)

$url = “http://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs()?`$expand=Runbook&`$filter=(Status eq ‘Running’) and (Runbook/Name eq ‘0.1 Runbook B‘)&`$select=Runbook/Name,Status”
$request = [System.Net.HttpWebRequest]::Create($url)
$request.Credentials = $creds
$request.Timeout = 120000
$request.ContentType = “application/atom+xml,application/xml”
$request.Headers.Add(“DataServiceVersion”, “2.0;NetFx”)
$request.Method = “GET”

$response = $request.GetResponse()
$requestStream = $response.GetResponseStream()
$readStream=new-object System.IO.StreamReader $requestStream
$Output = $readStream.ReadToEnd()
$readStream.Close()
$response.Close()
$Output

#########################################################################################

Here is the output from the request when Runbook B is NOT running:

<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes”?>
<feed xml:base=”https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/&#8221; xmlns:d=”http://schemas.microsof
t.com/ado/2007/08/dataservices” xmlns:m=”http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&#8221; xmlns=”http://
http://www.w3.org/2005/Atom”&gt;
<title type=”text”>Jobs</title>
<id>https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs</id&gt;
<updated>2012-02-19T18:59:26Z</updated>
<author>
<name />
</author>
<link rel=”self” title=”Jobs” href=”Jobs” />
</feed>

Here is the output when Runbook B is currently running:

<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes”?>
<feed xml:base=”https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/&#8221; xmlns:d=”http://schemas.microsof
t.com/ado/2007/08/dataservices” xmlns:m=”http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&#8221; xmlns=”http://
http://www.w3.org/2005/Atom”&gt;
<title type=”text”>Jobs</title>
<id>https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs</id&gt;
<updated>2012-02-19T19:01:19Z</updated>
<link rel=”self” title=”Jobs” href=”Jobs” />
<entry m:etag=”W/&quot;datetime’2012-02-19T19%3A00%3A53.29’&quot;”>
<id>https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs(guid’4f104fcd-d626-421d-9f75-c8c83200
48e0′)</id>
<title type=”text”></title>
<published>2012-02-19T19:00:49-05:00</published>
<updated>2012-02-19T19:00:53-05:00</updated>
<author>
<name />
</author>
<link rel=”edit” title=”Job” href=”Jobs(guid’4f104fcd-d626-421d-9f75-c8c8320048e0′)” />
<link rel=”http://schemas.microsoft.com/ado/2007/08/dataservices/related/Runbook&#8221; type=”application/atom+xml;type=e
ntry” title=”Runbook” href=”Jobs(guid’4f104fcd-d626-421d-9f75-c8c8320048e0′)/Runbook”>
<m:inline>
<entry m:etag=”W/&quot;datetime’2012-02-19T03%3A57%3A55’&quot;”>
<id>https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Runbooks(guid’034d6f78-0529-4111-b31
7-24d75fb42493′)</id>
<title type=”text”>0.1 Runbook B</title>
<published>2012-02-19T03:57:20-05:00</published>
<updated>2012-02-19T03:57:55-05:00</updated>
<author>
<name />
</author>
<link rel=”edit” title=”Runbook” href=”Runbooks(guid’034d6f78-0529-4111-b317-24d75fb42493’)” />
<category term=”Microsoft.SystemCenter.Orchestrator.WebService.Runbook” scheme=”http://schemas.microsoft.com/
ado/2007/08/dataservices/scheme” />
<content type=”application/xml”>
<m:properties>
<d:Name>0.1 Runbook B</d:Name>
</m:properties>
</content>
</entry>
</m:inline>
</link>
<category term=”Microsoft.SystemCenter.Orchestrator.WebService.Job” scheme=”http://schemas.microsoft.com/ado/2007/0
8/dataservices/scheme” />
<content type=”application/xml”>
<m:properties>
<d:Status>Running</d:Status>
</m:properties>
</content>
</entry>
</feed>

So you can see in the output above, you can use link logic to find “<d:Status>Running</d:Status>” in the output from the query to determine if 0.1 Runbook B can be started.

Start Runbooks from SharePoint List   Leave a comment

I’ve moved everything from this blog over to jmattivi.blogspot.com and updated all of the scripts to have straight quotes.  If any don’t work as posted, please let me know!

For further posts please see jmattivi.blogspot.com.

Thanks!

 

After stopping all running/pending runbooks to perform maintenance on the SCOrch environment, it becomes cumbersome to start all runbooks that begin with a monitor date/time activity (especially when the number of runbooks to start climbs above 100….).

You can create a SharePoint list (Figure A) of runbooks that need to be started after maintenance (good to document nonetheless) that Orchestrator can reference to start all of them automatically!

The main field that we need to use is the RunbookID in the SP list.  I also use a field called “Active” in the list to exclude workflows that may not need started in case there is any reason that they shouldn’t be started for the time being.

Figure A

The workflow is made up of three runbooks.  A main which queries the SP list for the active runbook ids to start, the execute which starts the targeted runbook, and a seperate runbook to keep track of processed runbooks to later check for any errors.

Main (Figure B)

Figure B

The main starts by resetting a counter to cleanup from previous runs.  Then it uses the Microsoft SharePoint IP by Jeff Fanjoy (more info here http://orchestrator.codeplex.com/releases/view/75877) to query the list identified in the SP IP configuration in options.  Within the properties of the Get Active Runbooks activity, the filter is modified to choose the “Active” field set on the list object (Figure C).

Figure C

From the runbooks found in the list query, it will invoke the execute runbook with the runbook id and runbook name.  It also invokes the counter modification runbook with a parameter – increment (note this invoke must set the property to wait for completion – See Figure E).

Exploring the execute runbook that’s invoked in Figure D….it uses the Standard Logging IP (more info here http://orchestrator.codeplex.com/releases/view/76097).  It starts the targeted runbook (you can reference this from my previous post – https://jmattivi.wordpress.com/2012/01/08/scorch-powershell-startrunbook_part1/).  Upon success or failure to start the runbook, it invokes the counter modification runbook with a parameter – decrement (note this invoke must set the property to wait for completion – See Figure E).

Figure D

Figure E

Moving back to the Main runbook (Figure B), it waits for the counter value to be 0 – indicating processing has completed.  If not it hits a timeout after 15 minutes and sends an error email for investigation.  It then queries the Standard Logging table in the database for any failures to start runbooks from the execute runbook.  If errors are found, it uses a Powershell script to parse the flattened data back into multi-valued data and send that information in an email.  If no failures are found, it sends a success email that all targeted scheduled runbooks have been started successfully.